| 如果編寫(xiě)高效的數據庫代碼 |
| 作者: Builder.com 2006-10-08 05:0 PM |
|
作為一個(gè).NET開(kāi)發(fā)者,我們經(jīng)常會(huì )發(fā)現自己置身于SQL Server查詢(xún)和存儲過(guò)程當中,一個(gè)很好的例子就是我最近開(kāi)發(fā)的一個(gè)ASP.NET應用軟件。 該軟件已經(jīng)開(kāi)發(fā)完成并交付用戶(hù)進(jìn)行測試,這個(gè)軟件使用了一個(gè)先有的SQL Server數據庫,大部分T-SQL已經(jīng)包含在預先定義的存儲過(guò)程中了(也就是說(shuō),我并沒(méi)有編寫(xiě)它們),當我把軟件提交給用戶(hù)的時(shí)候,他們向我抱怨了性能問(wèn)題。瓶頸源于數據庫層,所以我花費了大量的時(shí)間來(lái)調整T-SQL以提升性能。 在這篇文章中,我將和您共享一些在項目中發(fā)現的技巧,我使用的是SQL Server,不過(guò)很多項目對所有的數據庫平臺都是適用的。 難以避免 盡管大部分企業(yè)都擁有數據庫管理員和開(kāi)發(fā)人員,但是很難避免對SQL Server的開(kāi)發(fā),這是開(kāi)發(fā)管理的迷題之一,很多數據庫開(kāi)發(fā)人員告訴我因為我知道軟件的需求,所以由我來(lái)編寫(xiě)查詢(xún),盡管這種邏輯很難爭辯,但是要想精通T-SQL確實(shí)非常困難,而同時(shí)作為開(kāi)發(fā)者還要學(xué)習.NET平臺的多個(gè)層面。但是,基本的T-SQL語(yǔ)言還是具有一致性的,因此,讓我們來(lái)看看如何編寫(xiě)高效的數據庫代碼。 優(yōu)化要點(diǎn) 和編寫(xiě)任何程序代碼一樣,構建T-SQL查詢(xún)的方法也不止一種,以下是提升性能的一些指導方針。 WHERE語(yǔ)句 您應當適用WHERE語(yǔ)句來(lái)控制返回的數據行的數量,如果不使用WHERE語(yǔ)句,SQL Server會(huì )執行對整個(gè)表格進(jìn)行掃描并返回所有的行(如果確實(shí)需要這樣做,您可以不必適用WHERE語(yǔ)句,但是所有其他的情況下都要使用WHERE語(yǔ)句。) 您應當使用WHERE語(yǔ)句來(lái)支持HAVING語(yǔ)句,當您將GROUP BY和HAVING語(yǔ)句一起使用的時(shí)候,GROUP BY會(huì )將數據行分為不同的組并聚合它們的值,然后HAVING語(yǔ)句會(huì )剔除不需要的組。在有些情況下,您可以編寫(xiě)只包含WHERE和GROUP BY的語(yǔ)句而不需要HAVING語(yǔ)句。 數據列 使用星號(*)可以在查詢(xún)中很容易地返回所有數據列的值,您應當只獲取必需的數據行。結果集合中的數據列越少,數據量就會(huì )越少,這樣網(wǎng)絡(luò )流量的負擔就會(huì )減小。性能的提升依賴(lài)于數據列的數量,所以對數據列進(jìn)行限定是一種良好的習慣。 避免指針 SQL Server的指針功能可以在掃描結果中進(jìn)行循環(huán),但是這一功能的代價(jià)就是性能。指針功能對于每夜的服務(wù)器任務(wù)來(lái)講是不錯的,但是要在您的應用軟件的代碼/過(guò)程中避免使用指針。最好使用選擇語(yǔ)句來(lái)返回需要的值并在客戶(hù)端處理這些數據。 有多少行? T-SQL的COUNT函數可以在查詢(xún)中返回項目的數量,但是使用這個(gè)函數的時(shí)候可以指定一個(gè)數據列,從而提高性能,原因在于SELECT COUNT(*)在表格中執行了一個(gè)全表格的掃描然后返回總數。 您可以在函數調用中指定一個(gè)數據列,如果只需要計算表格有多少數據行,您可以使用sysindexes表格(不必使用WHERE語(yǔ)句),在sysindexes表格中有一個(gè)名為ROWS的數據列,它包含了數據庫中所有表格的行數,以下的代碼可以返回指定表格的數據行數量: SELECT rows FROM sysindexes WHERE id = OBJECT_ID(‘table_name‘) AND indid < 2 唯一值 很多開(kāi)發(fā)者喜歡在查詢(xún)中使用DISTINCT選項,它允許您返回唯一的數據行數值,絕無(wú)重復,但是問(wèn)題在于它降低了性能,所以您應當在絕對需要的情況下使用它。 返回一部分數據行 您可能只需要一個(gè)查詢(xún)的子集,無(wú)論查詢(xún)可以返回的總數有多少,TOP操作符都可以幫您指定需要返回的項目的具體數字或者百分比,以下的查詢(xún)返回了10個(gè)項目: SELECT TOP 10 CustomerID FROM Northwind.dbo.Orders WHERE Freight < 50.0 或者,您可以在總結果中返回一定的百分比: SELECT TOP 5 percent CustomerID FROM Northwind.dbo.Orders WHERE Freight < 50.0 避免哪些代碼 您應當避免沒(méi)有任何功能的代碼,這聽(tīng)上去像是廢話(huà),但是我確實(shí)碰到了無(wú)數的含有不執行任何功能代碼的存儲過(guò)程,這可能是由于存儲過(guò)程的版本變化而遺留下來(lái)的,但是您應當刪除掉這些不需要的代碼,或者您可以將它們變?yōu)樽⑨專(zhuān)@樣可以避免任何性能上的損失。 使用數據庫服務(wù)器 您應當充分利用服務(wù)器平臺的優(yōu)勢使用存儲過(guò)程而不是在您的客戶(hù)端代碼中使用T-SQL,因為存儲過(guò)程是經(jīng)過(guò)服務(wù)器平臺優(yōu)化過(guò)的,所以應該一直使用存儲過(guò)程以確保代碼運行的效率,此外,視圖功能也應當用來(lái)替換大規模的查詢(xún)從而提高性能。 索引是您的朋友 如果正確使用索引可以提高查詢(xún)的性能,如何創(chuàng )建索引已經(jīng)超出了本文的范圍,但是有大量的資源提供了相關(guān)的信息。此外,SQL Server還提供了SQL Profiler工具來(lái)定位性能的瓶頸。 前路漫漫 即使您的.NET代碼通過(guò)了測試,一切也都按照計劃實(shí)現了功能,但是依然有很多數據庫端的工作要做,您可以通過(guò)多種方式來(lái)解決查詢(xún)的性能問(wèn)題,我希望本文所介紹的方法為您提供了一個(gè)起點(diǎn)。另外,您還可以使用SQL Server的工具來(lái)識別查詢(xún)相關(guān)的問(wèn)題。請在文章的討論區共享您在優(yōu)化查詢(xún)性能方面的經(jīng)驗。 |
聯(lián)系客服