1、 對(duì)查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。
2、 應(yīng)盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描。
3、 應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如: select id from t where num is null 可以在num上設(shè)置默認(rèn)值0,確保表中num列沒(méi)有null值,然后這樣查詢: select id from t where num=0
4、 應(yīng)盡量避免在 where 子句中使用 or 來(lái)連接條件,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如: select id from t where num=10 or num=20 可以這樣查詢: select id from t where num=10 union all select id from t where num=20
5、 下面的查詢也將導(dǎo)致全表掃描: select id from t where name like '%abc%' 若要提高效率,可以考慮全文檢索。
6、 in 和 not in 也要慎用,否則會(huì)導(dǎo)致全表掃描,如: select id from t where num in(1,2,3) 對(duì)于連續(xù)的數(shù)值,能用 between 就不要用 in 了: select id from t where num between 1 and 3
7、 如果在 where 子句中使用參數(shù),也會(huì)導(dǎo)致全表掃描。因?yàn)镾QL只有在運(yùn)行時(shí)才會(huì)解析局部變量,但優(yōu)化程序不能將訪問(wèn)計(jì)劃的選擇推遲到運(yùn)行時(shí);它必須在編譯時(shí)進(jìn)行選擇。然而,如果在編譯時(shí)建立訪問(wèn)計(jì)劃,變量的值還是未知的,因而無(wú)法作為索引選擇的輸入項(xiàng)。如下面語(yǔ)句將進(jìn)行全表掃描: select id from t where num=@num 可以改為強(qiáng)制查詢使用索引: select id from t with(index(索引名)) where num=@num
8、 應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行表達(dá)式操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如: select id from t where num/2=100 應(yīng)改為: select id from t where num=100*2
9、 應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如: select id from t where substring(name,1,3)='abc'--name以abc開(kāi)頭的id select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id 應(yīng)改為: select id from t where name like 'abc%' select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
10、 不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算,否則系統(tǒng)將可能無(wú)法正確使用索引。
12、 不要寫(xiě)一些沒(méi)有意義的查詢,如需要生成一個(gè)空表結(jié)構(gòu): select col1,col2 into #t from t where 1=0 這類代碼不會(huì)返回任何結(jié)果集,但是會(huì)消耗系統(tǒng)資源的,應(yīng)改成這樣: create table #t(...)
13、 很多時(shí)候用 exists 代替 in 是一個(gè)好的選擇: select num from a where num in(select num from b) 用下面的語(yǔ)句替換: select num from a where exists(select 1 from b where num=a.num)
28、 在所有的存儲(chǔ)過(guò)程和觸發(fā)器的開(kāi)始處設(shè)置 SET NOCOUNT ON ,在結(jié)束時(shí)設(shè)置 SET NOCOUNT OFF 。無(wú)需在執(zhí)行存儲(chǔ)過(guò)程和觸發(fā)器的每個(gè)語(yǔ)句后向客戶端發(fā)送 DONE_IN_PROC 消息。