:: DEVELOPER ZONE
The Index Merge (index_merge) method is used to retrieve rows with
several ref, ref_or_null, or range scans and merge
the results into one. This method is employed when the table condition
is a disjunction of conditions for which ref, ref_or_null,
or range could be used with different keys.
This ``join'' type optimization is new in MySQL 5.0.0, and represents a significant change in behavior with regard to indexes, because the old rule was that the server is only ever able to use at most one index for each referenced table.
In EXPLAIN output, this method appears as index_merge in the
type column. In this case, the key column contains a list of
indexes used, and key_len contains a list of the longest key parts
for those indexes.
Examples:
SELECT * FROMtbl_nameWHEREkey_part1= 10 ORkey_part2= 20; SELECT * FROMtbl_nameWHERE (key_part1= 10 ORkey_part2= 20) ANDnon_key_part=30; SELECT * FROM t1, t2 WHERE (t1.key1IN (1,2) OR t1.key2LIKE 'value%') AND t2.key1=t1.some_col; SELECT * FROM t1, t2 WHERE t1.key1=1 AND (t2.key1=t1.some_colOR t2.key2=t1.some_col2);
The Index Merge method has several access algorithms (seen in the
Extra field of EXPLAIN output):
intersection
union
sort-union
The following sections describe these methods in greater detail.
Note: The Index Merge optimization algorithm has the following known deficiencies:
If a range scan is possible on some key, an Index Merge is not considered. For example, consider this query:
SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
For this query, two plans are possible:
An Index Merge scan using the (goodkey1 < 10 OR goodkey2 < 20)
condition.
A range scan using the badkey < 30 condition.
However, the optimizer only considers the second plan. If that is not what
you want, you can make the optimizer consider index_merge by using
IGNORE INDEX or FORCE INDEX. The following queries are
executed using Index Merge:
SELECT * FROM t1 FORCE INDEX(goodkey1,goodkey2) WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30; SELECT * FROM t1 IGNORE INDEX(badkey) WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
If your query has a complex WHERE clause with deep
AND/OR nesting and MySQL doesn't choose the optimal plan,
try distributing terms using the following identity laws:
(xANDy) ORz= (xORz) AND (yORz) (xORy) ANDz= (xANDz) OR (yANDz)
The choice between different possible variants of the index_merge
access method and other access methods is based on cost estimates of
various available options.
© 1995-2005 MySQL AB. All rights reserved.

User Comments
Add your own comment.