- 相關(guān)推薦
SQL語(yǔ)句的優(yōu)化問(wèn)題教程
在實(shí)際的工作中,尤其是在生產(chǎn)環(huán)境里邊,SQL語(yǔ)句的優(yōu)化問(wèn)題十分的重要,它對數據庫的性能的提升也起著(zhù)顯著(zhù)的作用.我們總是在抱怨機器的性能問(wèn)題,總是在抱怨并發(fā)訪(fǎng)問(wèn)所帶來(lái)的瑣問(wèn)題,但是如果我們對沒(méi)一條SQL語(yǔ)句進(jìn)行優(yōu)化,盡管不能說(shuō)可以解決全部問(wèn)題,但是至少可以解決大部分問(wèn)題.
1.Top排序問(wèn)題.
我們經(jīng)常要對表某個(gè)字段進(jìn)行排序,然后取前N名.所以我們會(huì )寫(xiě)如下的SQL語(yǔ)句:
selecttop100*from表
orderbyScoredesc
如果表非常大的話(huà),那么這樣的操作是非常消耗資源的,因為SQLSERVER要對整個(gè)表進(jìn)行排序,然后取前N條記錄.這樣的造作是在Temdb里邊進(jìn)行的,所以極端的時(shí)候會(huì )報Log已滿(mǎn)這樣的錯誤.為了避免進(jìn)行全表的排序,我們要做的僅僅是在Score上建立索引,這樣因為Score索引的葉級是有序的,只要在Score所以的頁(yè)級取前100個(gè),然后根據書(shū)簽查找到實(shí)際的記錄,這樣對DB的性能就會(huì )有極大的提升.
2.同一天問(wèn)題.
我們經(jīng)常要查找和一個(gè)日期同一天的記錄,所以我們回寫(xiě)如下的SQL語(yǔ)句;
declare@DateTimedatetime
set@DateTime=getdate()
select*from表
whereconvert(10),F_Time,120)=convert(10),@DateTime,120)
但是這樣寫(xiě)的SQL語(yǔ)句帶來(lái)的問(wèn)題就是不能使用F_Time上的索引了.為了近可能的使用F_Time上的索引,我們可以使用時(shí)間段查詢(xún)的方式來(lái)代替上邊的語(yǔ)句.
declare@startdatetime
declare@enddatetime
declare@datetimedatetime
set@datetime=getdate()
tart=convert(10),@datetime,120)--一天的其始時(shí)間
set@end=dateadd(ss,-1,dateadd(d,1,@start))--一天的結束時(shí)間
select*from表whereF_Timebetween@startand@end
這樣就解決了使用不上索引的問(wèn)題.
3.利用索引進(jìn)行分組操作.】我們經(jīng)常要對某一字段進(jìn)行分組,而對另外一些字段進(jìn)行聚合操作.如果我們對分組的字段合理的使用索引,可以加快我們分組的速度.下邊以Northwind的Orders表為例:
--orders表的EmployeeID上建有索引.
selectEmployeeID,count(*)
fromorders
groupbyEmployeeID
--查看執行計劃,此查詢(xún)利用了EmployeeID上的索引.如改成如下查詢(xún):
selectEmployeeID,sum(Freight)
fromorders
groupbyEmployeeID
--查看執行計劃,此查詢(xún)則沒(méi)有使用EmployeeID上的索引.而是使用了全表掃描.那么原因是什么呢?是因為Freight沒(méi)有在EmployeeID的索引上,所以通過(guò)索引不能得到結果.而如果通過(guò)書(shū)簽查詢(xún)的成本太高,所以SQLSERVER選擇了使用全表掃描.而如果我們執行在EmployeeID和Freight上建立復合索引呢?
createindexidx_EmployeeIDonorders(EmployeeID,Freight)
--再次執行第二個(gè)查詢(xún).查看執行計劃.SQLSERVER使用的我們建立的索引.只需要使用索引就可以查詢(xún)到結果,極大的提高了我們的查詢(xún)速度.
【SQL語(yǔ)句的優(yōu)化問(wèn)題教程】相關(guān)文章:
SQL優(yōu)化大全09-09
oracle的sql語(yǔ)句01-21
SQL查詢(xún)語(yǔ)句大全10-24
SQL語(yǔ)句的理解原則10-05
mysql SQL語(yǔ)句積累參考10-02
SQL語(yǔ)句中的正則表達示07-28