執行計畫中存在索引跳掃步驟
存在索引跳掃說明查詢條件和索引定義不嚴格匹配
對於組合索引來說,在oracle8i之前,如果where字句中沒有組合索引的前導列(即建立索引時排在第一位的字段)的話,這個組合索引在sql語句中是不起任何作用的,在oracle9i中引入了跳躍式掃瞄,也就是如果在where字句中沒有前導列的話也可以使用組合索引後面的列進行索引掃瞄,條件就是前導列的distinct的值不能太多,比如100萬記錄中,前導列只有 "男","女" 兩個值 。
不過,oracle承認索引跳躍式掃瞄沒有直接索引查詢速度快,但可以這樣說,相比於整個表掃瞄(full table scan),索引跳躍式掃瞄的速度要快得多。
例子:create index ***_emp_id
on emp (***, emp_id) ;
select emp_name
from emp
where emp_id = 123;
通過執行計畫可以看出,oracle使用跳躍式索引掃瞄其實就是將上面的語句劃分為以下語句執行,相當於使用了***這個前導列,所以使用上了索引。
select emp_name from emp where *** = 'f' and emp_id = 123
union
select emp_name from emp where *** = 'm' and emp_id = 123;
對於高順序鍵(high order key)中的獨特值數目(也就是前導列distinct值太多),oracle的索引跳躍式掃瞄效能將會降低。如果主列(前導列)有50個不同值,根據上面的sql執行拆分分析,那麼oracle要發出50條查詢union才能找回結果 。
索引跳躍式掃瞄(index skip scan)適用於所有型別的復合b樹索引(包括唯一性索引和非唯一性索引),它使那些在where條件中沒有對目標索引的前導列指定查詢條件但同時又對該 索引的非前導列指定了查詢條件的目標sql依然可以用上該索引,這就像是在掃瞄該索引時跳過了它的前導列,直接從該索引的非前導列開始掃瞄一樣(實際的執行過程並非如此),這也是索引跳躍式掃瞄中"跳躍"(skip)一詞的含義。
為什麼在where條件中沒有對目標索引的前導列指定查詢條件但oracle依然可以用上該索引呢?這是因為oracle幫你對該索引的前導列的所有distinct值做了遍歷。
oracle中的索引跳躍式掃瞄僅僅適用於那些目標索引前導列的distinct值數量較少、後續非前導列的可選擇性又非常好的情形,因為索引跳躍式掃瞄的執行效率一定會隨著目標索引前導列的distinct值數量的遞增而遞減。
參考:
MySQL 8 0 索引特性2 索引跳躍掃瞄
mysql 8.0 實現了index skip scan,翻譯過來就是索引跳躍掃瞄。熟悉oracle的朋友是不是發現越來越像oracle了?再者,熟悉 mysql 5.7 的朋友是不是覺得這個很類似當時優化器的選項mrr?好了,先具體說下什麼 iss,我後面全部用 iss 簡稱。考慮以下的場景 表t...
索引掃瞄總是索引掃瞄麼?
問 使用nc掃瞄運算子,有方法知道索引是怎麼掃瞄的麼?這個問題的乙個答案是非聚集索引掃瞄總是掃瞄整個索引。答 是的,總是100 掃瞄運算子總是整個索引 但是有一些特定的情況並不是這樣。在這篇文章裡我想專門講下你總會碰到的乙個特定案例 在你的查詢裡有top,min或者max表示式。我們來看下面2個查詢...
Index Scans 索引掃瞄
官方文件鏈結位址 select department id,last name,salary from employees where salary 5000 order by department id,last name 50,atkinson,2800,rowid 60,austin,4800...