【摘 要】本文主要是對(duì)MS SQL Server數(shù)據(jù)庫(kù)查詢(xún)優(yōu)化技巧進(jìn)行了說(shuō)明和分析,對(duì)索引使用、查詢(xún)條件以及數(shù)據(jù)表的設(shè)計(jì)等進(jìn)行了闡述。
【關(guān)鍵詞】數(shù)據(jù)庫(kù);查詢(xún);優(yōu)化技巧
一、建立索引能夠提高查詢(xún)效率
在應(yīng)用數(shù)據(jù)庫(kù)的過(guò)程當(dāng)中是否應(yīng)用索引查詢(xún)是一個(gè)具有爭(zhēng)議性的話(huà)題,這主要是因?yàn)閷?duì)數(shù)據(jù)庫(kù)某列添加索引以后,在利用該索引對(duì)整個(gè)數(shù)據(jù)庫(kù)進(jìn)行查詢(xún)的時(shí)候就只會(huì)在索引范圍之內(nèi)進(jìn)行掃描,而不利用該索引對(duì)整個(gè)數(shù)據(jù)庫(kù)進(jìn)行查詢(xún)時(shí)所進(jìn)行的就是全表的掃描。在這樣一種狀況下,從性能的角度來(lái)看的話(huà),目標(biāo)表記錄的總數(shù)是固定的,因此在查詢(xún)結(jié)果比較少的時(shí)候索引查詢(xún)的效率才會(huì)相對(duì)比較高,查詢(xún)結(jié)果較多的時(shí)候索引查詢(xún)的效率反而會(huì)比較低,正是因?yàn)檫@樣,索引查詢(xún)的應(yīng)用與否才會(huì)成為一個(gè)具有爭(zhēng)議性的問(wèn)題。但在實(shí)際的應(yīng)用過(guò)程當(dāng)中,各種不同軟件的應(yīng)用目的不一,通常來(lái)說(shuō),記錄數(shù)較少的表查詢(xún)結(jié)果與記錄數(shù)的比值偏大,甚至能夠出現(xiàn)100%查詢(xún),但記錄數(shù)少的表查詢(xún)結(jié)果與記錄數(shù)的比值則偏小,由此認(rèn)為,至少應(yīng)當(dāng)對(duì)一些記錄數(shù)比較多的數(shù)據(jù)庫(kù)建立索引查詢(xún)來(lái)實(shí)現(xiàn)查詢(xún)效率的提高。
二、數(shù)據(jù)表設(shè)計(jì)對(duì)查詢(xún)性能的影響分析
(1)空值比較。在對(duì)數(shù)據(jù)表進(jìn)行定義的過(guò)程當(dāng)中會(huì)涉及到數(shù)據(jù)列的空值問(wèn)題,這主要是因?yàn)樵趯?shí)際的應(yīng)用過(guò)程當(dāng)中無(wú)疑會(huì)出現(xiàn)允許空值的狀況,但在定義數(shù)據(jù)表時(shí)如果允許空值設(shè)置的話(huà)就會(huì)出現(xiàn)is 1的查詢(xún)條件。一旦is 1查詢(xún)條件出現(xiàn)后續(xù)的查詢(xún)過(guò)程就是對(duì)全表進(jìn)行的掃描而不是索引掃描,具體來(lái)說(shuō),int當(dāng)中采用一些特殊的數(shù)字來(lái)作為默認(rèn)值,而字符串當(dāng)中則采用空串來(lái)作為默認(rèn)值。(2)字符類(lèi)型比較。MS SQL
Server2005當(dāng)中共有六類(lèi)字符串?dāng)?shù)據(jù)類(lèi)型,包括:varbinary、binary、nvarchar、nchar、varchar、char。在這六個(gè)字符串?dāng)?shù)據(jù)類(lèi)型當(dāng)中,binary、nchar、char是固定長(zhǎng)度的字符串,varbinary、nvarchar、varchar則是可變長(zhǎng)度的字符串,在應(yīng)用的過(guò)程當(dāng)中不同類(lèi)型也是可以互換使用的,因此要注意對(duì)其進(jìn)行區(qū)分。
三、條件表達(dá)式性能優(yōu)缺點(diǎn)分析
在進(jìn)行數(shù)據(jù)查詢(xún)的過(guò)程當(dāng)中,查詢(xún)結(jié)果在查詢(xún)語(yǔ)句中的表達(dá)方式有多種,且不同表達(dá)方式所得到的查詢(xún)效率有高有底,這也就是說(shuō),在進(jìn)行條件表達(dá)式的編寫(xiě)時(shí)也需要根據(jù)查詢(xún)結(jié)果的特點(diǎn)進(jìn)行選擇和應(yīng)用,下面主要是結(jié)合常用的幾種情況進(jìn)行說(shuō)明和分析。(1)!=或<>情況。我們?cè)趯?shí)際的查詢(xún)過(guò)程當(dāng)中應(yīng)當(dāng)盡可能的去避免不等條件的應(yīng)用,這主要是因?yàn)橐坏┰诓樵?xún)過(guò)程當(dāng)中使用不等條件就意味著后續(xù)查詢(xún)過(guò)程只能夠通過(guò)全面掃描來(lái)完成,索引掃描在其中是難以發(fā)揮作用的。通常情況下采用的是大于或小于的表達(dá)式來(lái)對(duì)不等條件進(jìn)行表示。(2)Like情況。Like情況主要是應(yīng)用于字符串的模糊查詢(xún),其具體的查詢(xún)表達(dá)形式同樣有多種:like a%、like%a和like a%a ,在這其中,只有l(wèi)ikea%既能應(yīng)用于索引掃描又能應(yīng)用于全表掃描,like%a和likea%a只能進(jìn)行全表掃描,正是因?yàn)檫@樣,我們?cè)谶M(jìn)行選擇和使用的時(shí)候就盡可能的避免后兩種表達(dá)方式。但是,在一些目標(biāo)列中字段過(guò)長(zhǎng)的時(shí)候,檢索方式會(huì)選擇為全文檢索,在這樣一種情況下則還是選擇like%a和likea%a更為合適。(3)in、not in 情況。在進(jìn)行查詢(xún)語(yǔ)言的設(shè)計(jì)時(shí),in的用法包括兩種,一種是后接條件集合,一種是后接子查詢(xún),下文中將對(duì)這樣兩種情況分別進(jìn)行說(shuō)明和分析。in后接條件集合,如果其數(shù)據(jù)量不大或者其對(duì)應(yīng)條件無(wú)索引時(shí),可以直接予以使用而不需要對(duì)其進(jìn)行優(yōu)化,相反,如果數(shù)據(jù)量較大或者其對(duì)應(yīng)條件有索引時(shí),就建議將所有的條件都集合起來(lái),并為每一個(gè)條件都單獨(dú)寫(xiě)sql語(yǔ)句,采用union或者是union all將所有的查詢(xún)結(jié)果進(jìn)行連接。在這里進(jìn)一步說(shuō)明union和union all之間的區(qū)別,union能夠?qū)Σ樵?xún)結(jié)果進(jìn)行有效的排序,并去除重復(fù)項(xiàng),而union all則無(wú)此功能,在實(shí)際的應(yīng)用過(guò)程當(dāng)中就可以根據(jù)需要排序與否來(lái)進(jìn)行選擇和使用。In后接子查詢(xún)時(shí),目標(biāo)表記錄數(shù)量如果明顯比子查詢(xún)表記錄數(shù)少的話(huà)就需要采用exists來(lái)代替in,必要的時(shí)候還可以在子查詢(xún)當(dāng)中建立索引。但需要注意的是,在一些能夠直接使用連接查詢(xún)方式的語(yǔ)句當(dāng)中就盡可能的不要使用in,這主要是因?yàn)閕n語(yǔ)句相當(dāng)于hash連接,其性能相對(duì)而言要低的多。Not in在任何狀況下應(yīng)用都不會(huì)使用索引,因此認(rèn)為在一些數(shù)據(jù)量大的數(shù)據(jù)庫(kù)當(dāng)中盡量不要使用,而not exists的子查詢(xún)則是可以應(yīng)用索引掃描的,因此有必要的時(shí)候就可以直接采用not exists加索引來(lái)對(duì)其進(jìn)行優(yōu)化。
通過(guò)上文的說(shuō)明和分析就可以看到,在進(jìn)行數(shù)據(jù)庫(kù)查詢(xún)時(shí)往往是沒(méi)有既定的方式和規(guī)則的,需要我們以查詢(xún)效率為目的來(lái)進(jìn)行創(chuàng)新、設(shè)計(jì)和嘗試。
參 考 文 獻(xiàn)
[1]王珊,薩師炫.?dāng)?shù)據(jù)庫(kù)系統(tǒng)概述(第四版)[M].北京:高等教育出版社,2006
[2]李輝,王至邀.一種多條件分頁(yè)查詢(xún)優(yōu)化方法的設(shè)計(jì)[J].計(jì)算機(jī)工程.2010(2)