mysql (ICP) 索引條件下推對比ORACLE進行說明
mysql (ICP) 索引條件下推對比ORACLE進行說明<br />
<br />
<br />
第一次看到這個名詞,與ORACLE FPD - filter push-down想到了一塊,但是後來才發現他們根本同一個東西,<br />
簡單的收ICP就是當索引包含所有的訪問欄位的時候,可以在根據前導列過濾掉條件的時候,同時過濾掉另外的<br />
條件,比如說<br />
CREATE TABLE TESTICP(A INT,B INT,C NAME);<br />
ALTER TABLE TESTTICP ADD KEY(A,B);<br />
<br />
<br />
SELECT * FROM TESTICP WHERE A=1 AND B <10<br />
的時候,如果未使用ICP就是透過A=1的條件返回結果集然後透過<br />
回表操作後然後過濾掉B<10的條件,這種情況下額外的並不滿足B<10的結果集透過回表操作,這樣加大了離散<br />
讀的壓力,如果瞭解ORACLE的朋友一定記得CLUSTER_FACTOR這個概念,他用於描述索引相對錶中資料的有序<br />
程度,其最大值為表的行數,最小值為表的塊數,越小代表索引和表的資料越相似,也就是表中這列是比較有序的<br />
,如果越大那麼回表的操作越耗時(離散讀取越厲害),這點雖然在MYSQL還不太瞭解但是一定會受到這樣的影響。<br />
所以及早的過濾掉不需要的資料是非常必要的。在ORACLE中這也許不是問題,但是MYSQL知道5.6才引入了ICP。<br />
我們先來看看ORACLE的執行計劃<br />
使用指令碼:<br />
CREATE TABLE TESTICP(A INT,B INT,C varchar2(20));<br />
declare <br />
i number(10);<br />
begin <br />
for i in 1..1000<br />
loop<br />
insert into TESTICP<br />
values(i,i,'gaopeng');<br />
end loop;<br />
end;<br />
SELECT * FROM TESTICP WHERE A=1 AND B <10;<br />
<br />
<br />
--------------------------------------------------------------------------------<br />
Plan hash value: 446810821<br />
--------------------------------------------------------------------------------<br />
| Id | Operation | Name | Rows | Bytes | Cost (%CPU<br />
--------------------------------------------------------------------------------<br />
| 0 | SELECT STATEMENT | | 1 | 38 | 3 (0<br />
| 1 | TABLE ACCESS BY INDEX ROWID| TESTICP | 1 | 38 | 3 (0<br />
|* 2 | INDEX RANGE SCAN | TESTICP_INDEX | 1 | | 2 (0<br />
--------------------------------------------------------------------------------<br />
Predicate Information (identified by operation id):<br />
---------------------------------------------------<br />
2 - access("A"=1 AND "B"<10)<br />
<br />
<br />
非常加單我們只需要看到access("A"=1 AND "B"=1)就知道是透過"A"=1 AND "B"=1來訪問索引的<br />
如果是FILTER B=1我們可以理解為訪問索引後過濾的。<br />
SQL> explain plan for select * from testicp where a=1 and c='gtest';<br />
Explained<br />
<br />
<br />
SQL> select * from table(dbms_xplan.display);<br />
PLAN_TABLE_OUTPUT<br />
--------------------------------------------------------------------------------<br />
Plan hash value: 446810821<br />
--------------------------------------------------------------------------------<br />
| Id | Operation | Name | Rows | Bytes | Cost (%CPU<br />
--------------------------------------------------------------------------------<br />
| 0 | SELECT STATEMENT | | 1 | 38 | 3 (0<br />
|* 1 | TABLE ACCESS BY INDEX ROWID| TESTICP | 1 | 38 | 3 (0<br />
|* 2 | INDEX RANGE SCAN | TESTICP_INDEX | 1 | | 2 (0<br />
--------------------------------------------------------------------------------<br />
Predicate Information (identified by operation id):<br />
---------------------------------------------------<br />
1 - filter("C"='gtest')<br />
2 - access("A"=1)<br />
Note<br />
-----<br />
- dynamic sampling used for this statement (level=2)<br />
19 rows selected<br />
<br />
<br />
如果我們改變為and c='gtest'<br />
可以看到 filter("C"='gtest'),這就是所謂的過濾。是索引回表後過濾的。<br />
<br />
<br />
但這一切在ORACLE認為理所當然的東西到了MYSQL到了5.6才實現。我們透過MYSQL來做一下<br />
指令碼使用:<br />
<br />
<br />
<br />
<br />
create table testicp(A INT,B INT,C varchar(20));<br />
delimiter //<br />
create procedure myproc3() <br />
begin <br />
declare num int; <br />
set num=1; <br />
while num <= 1000 do <br />
insert into testicp values(num,num,'gaopeng'); <br />
set num=num+1;<br />
end while;<br />
end//<br />
call myproc3() //<br />
delimiter ;<br />
alter table testicp add key(a,b);<br />
<br />
explain select * from testicp where a=1 and b<10;<br />
mysql> explain select * from testicp where a=1 and b<10;<br />
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------+<br />
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |<br />
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------+<br />
| 1 | SIMPLE | testicp | range | A | A | 10 | NULL | 1 | Using index condition |<br />
+----+-------------+---------+-------+---------------+------+---------+------+------+-----------------------+<br />
這裡使用關鍵字Using index condition加以說明,他受引數<br />
optimizer_switch='index_condition_pushdown=on' <br />
影響,如果我們設定optimizer_switch='index_condition_pushdown=off'再來看一下<br />
set optimizer_switch='index_condition_pushdown=off'<br />
mysql> explain select * from testicp where a=1 and b<10;<br />
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+<br />
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |<br />
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+<br />
| 1 | SIMPLE | testicp | range | A | A | 10 | NULL | 1 | Using where |<br />
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+<br />
1 row in set (0.01 sec)<br />
可以看到這裡變成了Using where,這代表沒有使用icp。<br />
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30633755/viewspace-1871648/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL索引條件下推的簡單測試MySql索引
- MySQL:關於ICP特性的說明(未完)MySql
- MySql索引下推知識分享MySql索引
- 【原創】MySQL 模擬條件索引MySql索引
- Mysql索引的使用-組合索引+跳躍條件MySql索引
- 五分鐘搞懂MySQL索引下推MySql索引
- MySQL學習筆記:組合索引-索引下推MySql筆記索引
- 【原創】MySQL 模擬條件索引薦MySql索引
- Mysql:好好的索引,為什麼要下推?MySql索引
- MySQL索引下推,原來這麼簡單!MySql索引
- Mysql索引的使用 - 組合索引 + 範圍條件的處理MySql索引
- oracle 索引升降序及排序條件 對查詢計劃的影響Oracle索引排序
- 【TcaplusDB知識庫】條件過濾說明與更新
- Oracle 條件索引 case when 報錯解決方案Oracle索引
- MySQL 針對 like 條件的優化MySql優化
- 【索引】Oracle之不可見索引和虛擬索引的比對索引Oracle
- Percona MySQL 5.6 WHERE 條件中 OR 的索引測試MySql索引
- 【索引】反向索引--條件 範圍查詢索引
- HttpClientFactory 使用說明 及 對 HttpClient 的回顧和對比HTTPclient
- python如何對陣列內的元素進行條件運算?Python陣列
- ORACLE執行計劃 explain說明OracleAI
- 效能優化:索引下推優化索引
- 說說MySQL索引相關MySql索引
- 【MYSQL】InnoDB行溢位資料說明MySql
- mysql 版本說明MySql
- 倒排索引及ES相關概念對比MySQL索引MySql
- 【索引】反向索引--條件 範圍查詢(二)索引
- 從InnoDB 索引執行簡述 聚集索引和非聚集索引、覆蓋索引、回表、索引下推索引
- 『忘了再學』Shell基礎 — 28、AWK中條件表示式說明
- C# 針對特定的條件進行鎖操作,不用lock,而是mutexC#Mutex
- Pandas根據篩選條件對指定excel列進行篩選!神器!Excel
- Oracle 執行計劃(Explain Plan) 說明OracleAI
- Oracle 執行計劃(Explain Plan) 說明OracleAI
- Rust 在 cargo 中進行條件編譯RustCargo編譯
- 使用Excel資料進行條件刪除Excel
- MySQL版本對varchar的定義和限制條件MySql
- Oracle Latch 說明Oracle
- Oracle Namespace 說明Oraclenamespace