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