假設有2個這樣的SQL
SELECT * FROM table WHERE a = 1 AND c = 3; // c不走索引
SELECT * FROM table WHERE a = 1 AND b < 2 AND c = 3; // c不走索引
假設資料 表T (a,b,c) rowid 為實體位置
rowid a b c
(1) 1 1 1
(2) 2 1 13
(3) 2 2 14
(4) 1 3 3
(5) 2 3 12
(6) 1 2 5
(7) 2 3 9
(8) 1 2 2
(9) 1 3 6
(10) 2 2 11
(11) 2 2 8
(12) 1 1 7
(13) 2 3 15
(14) 1 1 4
(15) 2 1 10
當你建立一個索引 create index xxx on t(a,b), 則索引檔案邏輯上等同于如下
a b rowid
1 1 1
1 1 12
1 1 14
1 2 6
1 2 8
1 3 4
1 3 9
2 1 2
2 1 15
2 2 3
2 2 10
2 2 11
2 3 5
2 3 7
2 3 13
當select * from T where a=1 and b=3 的時候, 資料庫系統可以直接從索引檔案中直接二分法找到A=1的記錄,然後再B=3的記錄。
但如果你 where b=3 則需要周遊這個索引表的全部!
多列索引是先按照第一列進行排序,然後在第一列排好序的基礎上再對第二列排序,如果沒有第一列的話,直接通路第二列,那第二列肯定是無序的,直接通路後面的列就用不到索引了。
你可以認為聯合索引是闖關遊戲的設計
例如你這個聯合索引是state/city/zipCode
那麼state就是第一關 city是第二關, zipCode就是第三關
你必須比對了第一關,才能比對第二關,比對了第一關和第二關,才能比對第三關
你不能直接到第二關的
索引的格式就是第一層是state,第二層才是city
如果你單獨為abc建立索引的話,(a,b,c)的意思就是先找a,然後在剩下的東西裡面找b,然後在剩下的東西裡面找c(當然你可以不這麼實作但是他們是等價的)。這個時候b和c的索引起不到任何幫助。
實戰例子: https://www.cnblogs.com/developer_chan/p/9223671.html