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列沒有null值,然后這樣查詢:
select id from t where num=0
4.應(yīng)盡量避免在 where 子句中使用 or 來連接條件蚂踊,否則將導(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)化程序不能將訪問計(jì)劃的選擇推遲到運(yùn)行時(shí)靡菇;它必須在編譯時(shí)進(jìn)行選擇。然而米愿,如果在編譯時(shí)建立訪問計(jì)劃厦凤,變量的值還是未知的,因而無法作為索引選擇的輸入項(xiàng)吗货。如下面語句將進(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開頭的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)將可能無法正確使用索引脖母。
11.在使用索引字段作為條件時(shí),如果該索引是復(fù)合索引闲孤,那么必須使用到該索引中的第一個(gè)字段作為條件時(shí)才能保證系統(tǒng)使用該索引谆级,否則該索引將不會(huì)被使用烤礁,并且應(yīng)盡可能的讓字段順序與索引順序相一致。
12.不要寫一些沒有意義的查詢肥照,如需要生成一個(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)
用下面的語句替換:
select num from a where exists(select 1 from b where num=a.num)