吳凱佳 陳少琴 李結(jié)映
摘要:在日常的工作中,或多或少會遇到一些較為復(fù)雜的sQL語句,當(dāng)我們發(fā)現(xiàn)這些語句執(zhí)行得慢時,總是會想辦法對其修改,讓它變得更快一些。本文探討研究了sQL SER VER下SQL的語句調(diào)優(yōu)方法。
關(guān)鍵詞:sQL;優(yōu)化;調(diào)優(yōu)
中圖分類號:TP311.1 文獻(xiàn)標(biāo)識碼:A 文章編號:1007-9416(2020)05-0051-01
1背景
一般在應(yīng)用中,糟糕的SQL語句是造成系統(tǒng)性能低下的最主要原因,例如大小寫的不統(tǒng)一、同樣的sQL語句不同的寫法等。當(dāng)業(yè)務(wù)數(shù)據(jù)量相對較少時,一些sQL的執(zhí)行效率對程序運(yùn)行效率的影響不太明顯,隨著數(shù)據(jù)量的增加,SQL的執(zhí)行效率對程序的運(yùn)行效率的影響逐漸增大,糟糕的sQL語句會使情況變得越來越嚴(yán)重,此時對sQL的優(yōu)化就很有必要。
2SQL優(yōu)化的一些方法
(1)通配符中Like的使用需注意,如select id,name fromusednfo where naille like%name%;或select id,name fromuserinfo where name like%name;該寫法由于name前面用了“%”,會造成全表的掃描,效率低下,select id,name from userinfowhere name likename%;這樣的的寫法執(zhí)行效率快很多。
(2)避免在Where子句中對字段進(jìn)行函數(shù)操作,where子句‘一左邊不要出現(xiàn)函數(shù)、算數(shù)運(yùn)算或者其他表達(dá)式運(yùn)算。如select id fromuserinfo where substring(name,l,6)=‘xiaomi;該語句對字段進(jìn)行了函數(shù)處理,會導(dǎo)致查詢分析器放棄了索引的使用。正確的寫法應(yīng)為select id from userinfo where name likexiaomi%。
(3)在子查詢當(dāng)中,盡量用exists代替in,如select name fromusennfo a where id in(select id from userinfo b);可以改為select naille from userinfo a where exists(select l from userinfob where id=a.id)。
(4)where子句中盡量不要使用iS null或iS not null對字段進(jìn)行判斷,例如:select id from userinfo where name iS null;盡量在數(shù)據(jù)庫字段中不出現(xiàn)null,如果查詢的時候條件為iS null,索引將不會被使用,造成查詢效率低,因此數(shù)據(jù)庫在設(shè)計(jì)的時候,盡可能將某個字段可能為空的時候設(shè)置默認(rèn)值,那么查詢的時候可以根據(jù)默認(rèn)值進(jìn)行查詢,比如name字段設(shè)置為0,查詢語句可以修改為se-lect id from userinfo where name=0。
(5)避免在where子句使用or作為鏈接條件,如select id fromuserinfo where name=xiaomingor name=xiaowang;可以改寫為:select id from usefinfo where name=xiaomingunionall select id from userinfo where name='xiaowang'。
(8)一些沒有意義的查詢?nèi)纾簊elect coll,c012 into#t from twhere l=O;這類代碼不會返回任何結(jié)果集,但是會消耗系統(tǒng)資源,如需要生成一個空表結(jié)構(gòu),應(yīng)改成:create table#t(…)。
(9)并不是所有索引對查詢都有效,sQL是根據(jù)表中數(shù)據(jù)來進(jìn)行查詢優(yōu)化的,當(dāng)索引列有大量數(shù)據(jù)重復(fù)時,sQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那么即使在seX上建了索引也對查詢效率起不了作用。
(10)盡可能使用varchari代替har,因?yàn)槭紫茸冮L字段存儲空間小,可以節(jié)省存儲空間,其次對于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些。
(u)避免頻繁創(chuàng)建和刪除臨時表,以減少系統(tǒng)表資源的消耗。臨時表并不是不可使用,適當(dāng)?shù)厥褂盟鼈兛梢允鼓承├谈行?,例如,?dāng)需要重復(fù)引用大型表或常用表中的某個數(shù)據(jù)集時。但是對于一次性事件,最好使用導(dǎo)出表。
(12)在新建臨時表時,如果一次性插入數(shù)據(jù)量很大,可以使用select into代替create table,避免造成大量log,以提高速度,如果數(shù)據(jù)量不大,為了緩和系統(tǒng)表的資源,應(yīng)Ygcreate table,然后insert。
(13)如果使用到了臨時表,在存儲過程的最后務(wù)必將所有的臨時表顯式刪除,先truncate table,然后drop table,這樣可以避免系統(tǒng)表的較長時間鎖定。
3結(jié)語
要對復(fù)雜的sQL進(jìn)行優(yōu)化,語句的執(zhí)行順序可謂是重中之重,我們只有明確了執(zhí)行順序,才能在后續(xù)簡化sQL的過程中有的放矢的進(jìn)行。否則,如果方向錯了,再努力也是徒勞。所以我們要做到不但會寫sQL,還要做到寫出性能優(yōu)良的sQL。