為什么mysql innodDB中組合索引中范圍查詢后的條件索引會失效?
一、mysql innodDB中組合索引中范圍查詢后的條件索引會失效的原因
表建立聯合索引(a,b,c),查詢條件a=1,b>2,c=3,此時c條件的索引會失效。簡單點來說,該組合索引是一個以a字段排序而b與c相對有序的B+樹,引擎可以通過二分查找定位到a=1的數據,b在a=1確定得情況下是有序的(所以b的有序是相對的),依然可以通過二分查找取出所有b大于2的數據,但這些數據的b字段可能有很多個不同的值,所以c字段是無序的,無法用二分查找來查詢c=3的數據,故c用不到索引。
當進行范圍查詢操作時,MySQL需要對組合索引中的非范圍查詢條件逐個進行檢查,以過濾掉不符合要求的記錄,直至掃描到范圍查詢條件時,由于范圍查詢操作具有不連續的特點,因此這個范圍查詢條件之后的記錄數據量會變得非常大,通常會超過MySQL的最大行數限制,這就導致了MySQL放棄使用這個組合索引,而改為全表掃描(full table scan)來獲取結果。這也是為什么范圍查詢操作容易導致MySQL查詢性能降低的原因之一。
例如存在索引數據如:(a=1,b=3,c=3),(a=1,b=4,c=0),(a=1,b=4,c=3),(a=1,b=4,c=0)。上述數據均滿足a=1&b>2,但是c的數據卻不是連續的,所以沒有辦法通過c索引進行過濾,所以字段c并不能夠參與到索引刷選中。
二、組合索引
1、組合索引的使用
本文中組合索引的定義為(MySQL):
ALTER TABLE table_name ADD INDEX (col1,col2,col3);
2、組合索引的本質
當創建(col1,col2,col3)組合索引時,相當于創建了(col)單列索引,(clo1,clo2)組合索引以及(col1,col2,col3)組合索引想要索引生效,只能使用col1和col1,col2和col1,col2,col3三種組合;當然,col1,col3組合也可以,但實際上只用到了col1的索引,col3并沒有用到。
3、示例
組合索引相當于一個按照姓氏——名字的一個電話簿,只能先確定姓氏才可以命中索引,下列可以正確命中組合索引的語句( = 和IN直接的字段都可以亂序,MySQL的查詢優化器可以優化成索引識別的形式)
使用到索引的情況如下:
col_a = "some value"col_a = "some value" and col_b = "some value"col_a = "some value" and col_c = "some value"col_a = "some value" and col_b = "some value" and col_c = "some value"col_a = "some value" and col_c = "some value" and col_b = "some value"col_b = "some value" and col_a = "some value" and col_c = "some value"col_b = "some value" and col_c = "some value" and col_a = "some value"col_c = "some value" and col_a = "some value" and col_b = "some value"col_c = "some value" and col_b = "some value" and col_a = "some value"
未使用索引的情況:
col_b = "some value"col_c = "some value"col_b = "some value" and col_c = "some value"col_c = "some value" and col_b = "some value"
總結,組合索引從最左開始組合,只要包含名列前茅列的查詢都會用到該組合索引。
4、為什么要使用組合索引
減少開銷:建一個聯合索引(col1,col2,col3),實際相當于建了(col1),(col1,col2),(col1,col2,col3)三個索引。每多一個索引,都會增加寫操作的開銷和磁盤空間的開銷。對于大量數據的表,使用組合索引會大大的減少開銷。覆蓋索引:對組合索引(col1,col2,col3),如果有如下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那么MySQL可以直接通過遍歷索引取得數據,而無需回表,這減少了很多的隨機io操作。減少io操作,特別的隨機io其實是dba主要的優化策略。所以,在真正的實際應用中,覆蓋索引是主要的提升性能的優化手段之一。效率高:索引列越多,通過索引篩選出的數據越少。5、SQL中組合索引和普通索引區別
組合索引中列的順序非常重要,從左原則:a,ab,ba,abc。
單個索引:一個一個起作用,也就是說有三個單個索引,哪個條件查詢在前哪個起作用,其他不起作用。
結論:
一般來說,列表搜索需要多個列查詢,此時就可以使用聯合索引,都是and的關系。什么時候需要創建索引:
where條件會經常出現的,并且當前表的數量比較大。where條件中是用and而非or的時候。組合索引比單個索引更適合,因為索引占用一定磁盤空間,也就說明有一定的開銷,如果多個單個索引比較多,那么多資源的浪費也比較多,組合索引相當于對多個列建索引,并且只建一次,and條件下非常適合。延伸閱讀1:MySQL簡介
MySQL是一個關系型數據庫管理系統,由瑞典MySQL AB 公司開發,屬于 Oracle 旗下產品。MySQL 是最流行的關系型數據庫管理系統之一,在 WEB 應用方面,MySQL是較好的 RDBMS (Relational Database Management System,關系數據庫管理系統) 應用軟件之一。

猜你喜歡LIKE
相關推薦HOT
更多>>
MySQL普通索引不等于為什么會失效?
一、MySQL普通索引不等于會失效的原因1、列數據類型不匹配如果查詢條件中的列類型與索引列類型不匹配,MySQL無法使用索引進行優化。例如,索引...詳情>>
2023-10-18 11:14:01
為什么關系型數據庫系統不易于scaling out(橫向擴展)?
一、為什么關系型數據庫系統不易于scaling out(橫向擴展)因為傳統的SQL數據庫沒想到要分片存儲,而現在的NewSQL開始考慮到這些問題了。當然分...詳情>>
2023-10-18 10:49:50
MySQL InnoDB引擎中的各種鎖具體是怎么實現的?
一、MySQL InnoDB引擎中的各種鎖的實現方式MySQL InnoDB引擎中的各種鎖是通過多種機制實現的1、共享鎖(Shared Lock)和排他鎖(Exclusive Lock...詳情>>
2023-10-18 10:26:59
Android怎么連接遠程數據庫?
一、Android連接遠程數據庫的方法1、確保遠程數據庫可以遠程訪問首先,確保您的遠程數據庫允許遠程連接。這通常需要在數據庫服務器的配置中啟用...詳情>>
2023-10-18 10:09:10熱門推薦
常用JS前端開發框架有哪些?
沸事務并發控制s2pl和s2pl有何區別?
熱為什么一臺電腦可以安裝多個SQL Server實例?
熱MySQL普通索引不等于為什么會失效?
新為什么關系型數據庫系統不易于scaling out(橫向擴展)?
MySQL InnoDB引擎中的各種鎖具體是怎么實現的?
Android怎么連接遠程數據庫?
為什么MySQL在innodb引擎中即使使用了MVCC機制仍然會出現丟失更新?
IO多路復用中select、poll、epoll之間的區別?
讀寫分離為什么能夠提升性能?
為什么mysql innodDB中組合索引中范圍查詢后的條件索引會失效?
為什么noteexpress不能建立數據庫也不能打開別的數據庫?
計算機前端是什么?
APP中集成移動端車牌識別系統都能達到什么效果?
技術干貨






