原則:避免全表掃描
數(shù)據(jù)量大的時(shí)候近刘,應(yīng)盡量避免全表掃描熙尉,應(yīng)考慮在 where 及 order by 涉及的列上建立索引药有,建索引可以大大加快數(shù)據(jù)的檢索速度毅戈。 但是苹丸,有些情況索引是不會(huì)起效的:
- 應(yīng)盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描苇经。
- 應(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 - 盡量避免在 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 - 下面的查詢也將導(dǎo)致全表掃描:
select id from t where name like ‘%abc%’
若要提高效率施流,可以考慮全文檢索。 - 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 - 如果在 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 - 應(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 - 應(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 ‘a(chǎn)bc%’
select id from t where createdate>=’2005-11-30′ and createdate<’2005-12-1′ - 不要在 where 子句中的“=”左邊進(jìn)行函數(shù)鲜侥、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算,否則系統(tǒng)將可能無法正確使用索引诸典。
- 在使用索引字段作為條件時(shí)描函,如果該索引是復(fù)合索引,那么必須使用到該索引中的第一個(gè)字段作為條件時(shí)才能保證系統(tǒng)使用該索引狐粱,否則該索引將不會(huì)被使用舀寓,并且應(yīng)盡可能的讓字段順序與索引順序相一致。
- 不要寫一些沒有意義的查詢肌蜻,如需要生成一個(gè)空表結(jié)構(gòu):
select col1,col2 into #t from t where 1=0
這類代碼不會(huì)返回任何結(jié)果集互墓,但是會(huì)消耗系統(tǒng)資源的,應(yīng)改成這樣:
create table #t(…) - 很多時(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)