原文鏈接:https://blog.csdn.net/Abysscarry/article/details/80792876
一、聯合索引測試
注:Mysql版本為 5.7.20
我們為userId
, mobile
, billMonth
三個字段添加上聯合索引!
1.查詢條件為 mobile and userid
EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND userid='2222'
- 1
調換了查詢條件的順序,發現聯合索引依舊有效
2.查詢條件為 userid or mobile
EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' OR mobile='13281899972'
- 1
把 and
換成 or
,發現聯合所索引無效!
3.查詢條件為 userid and billMonth
EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND billMonth='2018-04'
- 1
這兩個條件分別位於聯合索引位置的第一和第三,測試聯合索引依舊有效,但是key_len比1中的變小了!
二、單列索引測試
創建三個單列索引:
1.查詢條件為 userid and mobile and billMonth
EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND mobile='13281899972' AND billMonth='2018-04'
- 1
我們發現三個單列索引只有 userid
有效(位置為查詢條件第一個),其他兩個都沒有用上
2.查詢條件為 mobile and billMonth
EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND billMonth='2018-04'
- 1
我們發現此處兩個查詢條件只有 mobile
有效(位置也為查詢條件第一個),后面的無效
3.查詢條件為 userid or mobile
EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' OR mobile='13281899972'
- 1
這次把 and
換成 or
,發現兩個查詢條件都用上索引了!
三、結論
通俗理解:
利用索引中的附加列,您可以縮小搜索的范圍,但使用一個具有兩列的索引 不同於使用兩個單獨的索引。復合索引的結構與電話簿類似,人名由姓和名構成,電話簿首先按姓氏對進行排序,然后按名字對有相同姓氏的人進行排序。如果您知道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更為有用,但如果您只知道名不姓,電話簿將沒有用處。
所以說創建復合索引時,應該仔細考慮列的順序。對索引中的所有列執行搜索或僅對前幾列執行搜索時,復合索引非常有用;僅對后面的任意列執行搜索時,復合索引則沒有用處。
重點:
多個單列索引在多條件查詢時只會生效第一個索引!所以多條件聯合查詢時最好建聯合索引!
最左前綴原則:
顧名思義是最左優先,以最左邊的為起點任何連續的索引都能匹配上,
注:如果第一個字段是范圍查詢需要單獨建一個索引
注:在創建聯合索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。這樣的話擴展性較好,比如 userid
經常需要作為查詢條件,而 mobile
不常常用,則需要把 userid
放在聯合索引的第一位置,即最左邊
同時存在聯合索引和單列索引(字段有重復的),這個時候查詢mysql會怎么用索引呢?
這個涉及到mysql本身的查詢優化器策略了,當一個表有多條索引可走時, Mysql 根據查詢語句的成本來選擇走哪條索引;
有人說where查詢是按照從左到右的順序,所以篩選力度大的條件盡量放前面。網上百度過,很多都是這種說法,但是據我研究,mysql執行優化器會對其進行優化,當不考慮索引時,where條件順序對效率沒有影響,真正有影響的是是否用到了索引!如果使用聯合索引,那么where條件也要盡量根據聯合索引的順序來,如果不按照順序來,索引也同樣會用到,但是在執行前,SQL優化器也會將條件調整為聯合索引的順序,既然可以直接避免這種情況,就沒必要再讓SQL優化器去處理,畢竟處理也是有開銷的。
聯合索引本質:
當創建(a,b,c)聯合索引時,相當於創建了(a)單列索引,(a,b)聯合索引以及(a,b,c)聯合索引
想要索引生效的話,只能使用 a和a,b和a,b,c三種組合;當然,我們上面測試過,a,c組合也可以,但實際上只用到了a的索引,c並沒有用到!
注:這個可以結合上邊的 通俗理解 來思考!
其他知識點:
1、需要加索引的字段,要在where條件中
2、數據量少的字段不需要加索引;因為建索引有一定開銷,如果數據量小則沒必要建索引(速度反而慢)
3、如果where條件中是OR關系,聯合索引不起作用
4、聯合索引比對每個列分別建索引更有優勢,因為索引建立得越多就越占磁盤空間,在更新數據的時候速度會更慢。另外建立多列索引時,順序也是需要注意的,應該將嚴格的索引放在前面,這樣篩選的力度會更大,效率更高。