索引的訪問方式主要是 索引查詢、索引掃瞄。
在執行計畫中為 index seek,適用於查詢少量資料。
對應隨機io,能快速的定位一條資料。
在執行計畫中為 index scan,適合掃瞄整個索引的資料。類似於全表掃瞄(只掃瞄索引)
對應順序io,io效率本身比較高。
索引查詢 和 索引掃瞄,單從io效率上來說,肯定是索引掃瞄的效率更高,因為順序io的效率高於隨機io的效率。
但是乙個索引查詢消耗的時間,肯定要遠小於索引掃瞄的時間,因為索引查詢只是定位少量記錄。
比如:a表有100w條資料,有索引idx_a,那麼查詢1條記錄,假設消耗的時間是0.00001秒,而掃瞄整個索引消耗時間是0.1秒(都為估算的時間)。
現在的sql:select * from a where id = 123456
查詢1條資料,那麼用索引查詢就是0.0001秒,而索引掃瞄還是0.1秒。
如果sql是:select country(*) from a
那麼,索引掃瞄可以滿足這個sql,消耗還是0.1秒,但如果用索引查詢,0.00001* 100w = 100秒(估算值,不一定是線性增長的)。
所以,對於不同的sql,sql server優化器會決定是用index seek,還是index scan。
參考:1.隱式轉換容易從索引查詢變成索引掃瞄
我們可以通過兩種方式避免sql做隱式轉換:
1:確保比較的兩者具有相同的資料型別。
2:使用強制轉換(explicit conversion)方式。
2.統計資訊缺失或者不正確容易導致索引掃瞄
3.where子句中的謂詞不是聯合索引的第一列
對於聯合索引最左邊一列存有統計資訊,其他列sqlserver不存統計資訊
4.where 子句裡串聯 索引字段使用函式 / 進行計算 會導致索引失效
where a+b = ... (索引為a,b聯合索引)
解決方法:
1).a+b生成乙個計算列
2).where a = ...and where b=...
5.=,>,<,>=,<=,between,已經部分like(like'%***') 可以使用索引查詢
優化like查詢:
1)在oracle中可以使用instr
select count(*) from table t where instr(t.code,'cod2%') > 0
2)在mysql中可以用locate和position函式,
如field like '%aaa%'可以改為locate('aaa',field) > 0
或position('aaa' in field)>0。
3)在sql server中,可以給字段建立全文索引,用contains來檢索資料
4)這裡多說一句,並不是所有%在前的模糊匹配都會走索引掃瞄
如果只select索引字段,或者select索引欄位和主鍵,也會走索引的。(where條件匹配中%在前)
6.where條件中使用標量函式回事索引查詢轉為索引掃瞄
索引掃瞄與索引查詢區別
掃瞄與查詢操作均是 sqlserver 從表或索引中讀取資料採用的迭代器,這些也是 sql server 支援的最基本的運算 幾乎在每乙個查詢計畫中都可以找到,因此理解它們的不同是很重要的,掃瞄是在整張表上進行處理,而索引是在整個頁級上進行處理,而查詢則返回特定謂詞上乙個或多個範圍內的資料行 下面讓...
索引掃瞄總是索引掃瞄麼?
問 使用nc掃瞄運算子,有方法知道索引是怎麼掃瞄的麼?這個問題的乙個答案是非聚集索引掃瞄總是掃瞄整個索引。答 是的,總是100 掃瞄運算子總是整個索引 但是有一些特定的情況並不是這樣。在這篇文章裡我想專門講下你總會碰到的乙個特定案例 在你的查詢裡有top,min或者max表示式。我們來看下面2個查詢...
索引 查詢型別和索引
當您考慮是否要對列建立索引時,請估計在查詢中使用列的方式,下表介紹了索引對其有用的查詢型別.表中的示例基於 adventureworks2008r2 示例資料庫,在 sql server management studio 中執行這些示例時.您可以通過顯示實際的執行計畫來檢視查詢優化器選擇的索引.有...