mysql的索引合并并不是什麼新特性。早在mysql5.0版本就已經實作。之是以還寫這篇博文,是因為好多人還一直保留着一條sql語句隻能使用一個索引的錯誤觀念。本文會通過一些示例來說明如何使用索引合并。
下面我們看下mysql文檔中對索引合并的說明:
the index merge method is used to retrieve rows with several range scans and to merge their results into one. the merge can produce unions, intersections, or unions-of-intersections of its underlying scans. this access method merges index scans from a single table; it does not merge scans across multiple tables.
根據官方文檔中的說明,我們可以了解到:
1、索引合并是把幾個索引的範圍掃描合并成一個索引。
2、索引合并的時候,會對索引進行并集,交集或者先交集再并集操作,以便合并成一個索引。
3、這些需要合并的索引隻能是一個表的。不能對多表進行索引合并。
簡單的說,索引合并,讓一條sql可以使用多個索引。對這些索引取交集,并集,或者先取交集再取并集。進而減少從資料表中取資料的次數,提高查詢效率。
在使用explain對sql語句進行操作時,如果使用了索引合并,那麼在輸出内容的type列會顯示 index_merge,key列會顯示出所有使用的索引。如下:

<img src="http://www.bo56.com/wp-content/uploads/2015/06/index_merge_sql.png" alt="index_merge_sql" width="1405" height="198" class="alignnone size-full wp-image-809" /></a></p>
在explain的extra字段中會以下幾種:
using union 索引取并集
using sort_union 先對取出的資料按rowid排序,然後再取并集
using intersect 索引取交集
你會發現并沒有 sort_intersect,因為根據目前的實作,想索引取交集,必須保證通過索引取出的資料順序和rowid順序是一緻的。是以,也就沒必要sort了。
從上面的兩個案例大家可以發現,相同模式的sql語句,可能有時能使用索引,有時不能使用索引。是否能使用索引,取決于mysql查詢優化器對統計資料分析後,是否認為使用索引更快。
是以,單純的讨論一條sql是否可以使用索引有點片面,還需要考慮資料。
資料結構和之前有所調整。主要調整有如下兩方面:
1、引擎從myisam改為了innodb。
2、組合索引中增加了id,并把id放在最後。
資料和上面的資料一樣。
相同的資料,相同的sql語句,隻是資料表結構有所調整,就從sort_union變為了union。有以下幾個原因:
1、隻要通過索引取出的資料已經按rowid進行了排序,就可以使用union。
2、組合索引中在最後加id字段,目的就是通過索引前兩個字段取出的資料是按id排序。
3、把引擎從myisam改為innodb,目的就是讓id和rowid的順序一緻。
資料結構和資料和union案例中的一緻。