mysql多條件查詢索引為什么只用到一個?


數據庫中查詢記錄時是否每次只能使用一個索引?

 

在網上看一些文章的時候,發現好幾次下面這樣的話:

如果經常需要同時對兩個字段進行AND查詢,那么使用兩個單獨索引不如建立一個復合索引,因為兩個單獨索引通常數據庫只能使用其中一個,而使用復合索引因為索引本身就對應到兩個字段上的,效率會有很大提高。

但是,往往都沒有說為什么?想知道以下問題:
1、是不是在任何情況下數據庫查詢一次只會使用到一個索引?
2、如果不是,那么什么情況下只會使用一個索引?
3、那分別是什么造成上面的查詢索引使用問題呢?


 

與其說是“數據庫查詢只能用到一個索引”,倒不是說是 和全表掃描/只使用一個索引的速度比起來,去分析兩個索引二叉樹更加耗費時間,所以絕大多數情況下數據庫都是是用一個索引。
如這條語句:

select count(1) from table1 where column1 = 1 and column2 = 'foo' and column3 = 'bar' 

我們來想象一下當數據庫有N個索引並且查詢中分別都要用上他們的情況:
查詢優化器(用大白話說就是生成執行計划的那個東西)需要進行N次主二叉樹查找[這里主二叉樹的意思是最外層的索引節點],此處的查找流程大概如下:
查出第一條column1主二叉樹等於1的值,然后去第二條column2主二叉樹查出foo的值並且當前行的coumn1必須等於1,最后去column主二叉樹查找bar的值並且column1必須等於1和column2必須等於foo。
如果這樣的流程被查詢優化器執行一遍,就算不死也半條命了,查詢優化器可等不及把以上計划都執行一遍,貪婪算法(最近鄰居算法)可不允許這種情況的發生,所以當遇到以下語句的時候,數據庫只要用到第一個篩選列的索引(column1),就會直接去進行表掃描了。

select count(1) from table1 where column1 = 1 and column2 = 'foo' and column3 = 'bar'

所以與其說是數據庫只支持一條查詢語句只使用一個索引,倒不如說N條獨立索引同時在一條語句使用的消耗比只使用一個索引還要慢。
所以如上條的情況,最佳推薦是使用index(column1,column2,column3) 這種聯合索引,此聯合索引可以把b+tree結構的優勢發揮得淋漓盡致:
一條主二叉樹(column=1),查詢到column=1節點后基於當前節點進行二級二叉樹column2=foo的查詢,在二級二叉樹查詢到column2=foo后,去三級二叉樹column3=bar查找。

 
來源:https://segmentfault.com/q/1010000003880137


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM