Mysql多列索引——最左精確匹配

若mysql的一張表上有一個多列索引,那麼在編寫where條件時,究竟哪些真正起到作用了呢,跟順序有關係嗎?

本文參考(http://blog.codinglabs.org/articles/theory-of-mysql-index.html

假設有如下的一張表:

DROP TABLE IF EXISTS testTable;
CREATE TABLE testTable
(
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name',
PORT VARCHAR(64) NOT NULL COMMENT 'port',
TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'launch date',
MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time',
CREATED TIMESTAMP NOT NULL COMMENT 'created time',
PRIMARY KEY(ID),
UNIQUE KEY INDEX_WORKER_NODE(HOST_NAME,PORT,LAUNCH_DATE,TYPE)
)COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB;

對應的查詢語句分別是

select * from testTable where PORT=3306 and Type=1
select * from testTable where PORT=3307 and HOST_NAME='172.21.1.1'
select * from testTable where PORT=3308 AND HOST_NAME='172.21.1.2' AND TYPE=2


那麼究竟用到了哪些索引呢?

第一句:沒用到索引尷尬,在聚集索引上從左至右依次掃描過濾;

第二句:用到了輔助索引INDEX_WORKER_NODE;

第三句:用到了輔助索引INDEX_WORKER_NODE,但是隻有HOST_NAME和PORT條件是通過索引完成的,條件TYPE是依次掃描過濾完成的;


爲什麼呢?

因爲輔助索引是B+樹實現的,雖然可以指定多個列,但是每個列的比較優先級不一樣,寫在前面的優先比較。一旦出現遺漏,在B+樹上就無法繼續搜索了(通過補齊等措施解決的除外),因此是按照最左連續匹配來的。既然是在B+樹上搜索,對於條件的比較自然是要求精確匹配(即"="和"IN")。不過順序倒是可以顛倒,因爲查詢優化器重排序一下就好了。

回頭來看,第一句,由於缺少HOST_NAME,只能在聚集索引的葉節點上,從左至右的掃描,挨個比對;

第二句,可以直接在輔助索引上查找,被找到的子樹的所有葉節點就是命中的記錄;

第三句,缺少LAUNCH_DATE條件,所以只能先依據HOST_NAME和PROT在輔助索引上查找,找到的主鍵值作爲候選記錄,然後到聚集索引上讀取對應記錄,再比較TYPE條件是否滿足。


發佈了42 篇原創文章 · 獲贊 19 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章