MySQL index problem about the condition before and after or

        Doesn't it mean that a sql statement can only use one index? But the following sql statement

SELECT * FROM `comment` WHERE `toconuid` = '10' or `tocomuid` = '10'

        The toconuid and tocomuid columns are single-column indexes respectively. After explain, both indexes are used, and extra is Using union(toconuid,tocomuid); Using where

        Here, it can be understood that MYSQL splits this statement into two statements

SELECT * FROM `comment` WHERE `toconuid` = '10'
union
SELECT * FROM `comment` WHERE `tocomuid` = '10'

1. Index merge optimization

        The index merge method is used to search rows through a range scan and combine the results into one. A merge produces a union, intersection, or union of the intersection of ongoing scans.

        In EXPLAIN output, the method appears as index_merge within the type column. In this case, the key column contains the indices used by a column, and key_len contains the longest key element of these indices.

E.g:

SELECT * FROM tbl_name WHERE key_part1 = 10 OR key_part2 = 20;
 
SELECT * FROM tbl_name WHERE (key_part1 = 10 OR key_part2 = 20) AND non_key_part=30;
 
SELECT * FROM t1, t2 WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%') AND t2.key1=t1.some_col;

SELECT * FROM t1, t2 WHERE t1.key1=1 AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);

 

2. There are several access algorithms for index merging methods 

        See the Extra field output by EXPLAIN, there are three index merge access algorithms: intersection, union, and sorting union.

        Note: The index merge optimization algorithm has several known pitfalls:

1). If some keywords can be range scanned, index merging is not considered. For example, the following query:

SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;

        There are two scenarios for this query:

        a. Use the condition (goodkey1 < 10 OR goodkey2 < 20) to perform an index merge scan.

        b. Range scan with badkey < 30 condition.

        However, the optimizer only considers the second option. If this is not what you want, you can make the optimizer consider index_merge by using IGNORE INDEX or FORCE INDEX. The following query is executed using index merging:

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;

2). If the query has a complex WHERE clause with a deep AND/OR nested relationship, MySQL does not choose this preferred solution, and tries to distribute the conditions through the following identification rules:

        a.(x AND y) OR z = (x OR z) AND (y OR z)

        b.(x OR y) AND z = (x AND z) OR (y AND z)

        The choice between the different variants of the index_merge access method and other access methods are based on cost estimates for each applicable option.

1. Index merge intersection access algorithm

        The access algorithm can be used when the WHERE clause combined with AND is converted to several range conditions of different keywords, each condition being one of the following:

        In this form, the index has exactly N parts (i.e. all index parts are included):

        a.key_part1=const1 AND key_part2=const2 ... AND key_partN=constN

        b. Range conditions for the primary key of any InnoDB or BDB table.

        Here are some examples:

SELECT * FROM innodb_table WHERE primary_key < 10 AND key_col1=20;
SELECT * FROM tbl_name WHERE (key1_part1=1 AND key1_part2=2) AND key2=2;

        The index merge intersection algorithm scans all used indexes simultaneously and produces the intersection of the row sequences received from the merged index scan.

        If the index used includes all the columns used in the query, all table records are not searched, and in this case the output of EXPLAIN contains the Using index in the Extra field. The following is an example of such a query:

SELECT COUNT(*) FROM t1 WHERE key1=1 AND key2=1;

        If an index is used that does not include all columns used in the query, all records are searched only if the range conditions for all used keywords are met.

        If a merge condition is a condition of the primary key of an InnoDB or BDB table, it is not used for record query, but is used to filter records searched using other conditions.

 

2. Index merge union access algorithm

        The applicable criteria of this algorithm are similar to those of the index merge method intersection algorithm. The algorithm can be used when the WHERE clause in conjunction with OR is transformed into several range conditions of different keywords, each condition being one of the following:

        In this form, the index has exactly N parts (i.e. all index parts are included):

        1).key_part1=const1 AND key_part2=const2 ... AND key_partN=constN

        2). The range condition of the primary key of any InnoDB or BDB table.

        3). A condition for the intersection algorithm of the index merge method to apply.

        Here are some examples:

SELECT * FROM t1 WHERE key1=1 OR key2=2 OR key3=3;
 
SELECT * FROM innodb_table WHERE (key1=1 AND key2=2) OR (key3='foo' AND key4='bar') AND key5=5;

 

3. Index Merge Sort Union Access Algorithm

        This access algorithm can be used when the WHERE clause combined with OR is converted to several range conditions of different keywords, but the index merge method combined with the algorithm is not suitable.

        Here are some examples:

SELECT * FROM tbl_name WHERE key_col1 < 10 OR key_col2 < 20;

 

Article source: http://www.educity.cn/wenda/590849.html

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326880227&siteId=291194637