Search code examples
mysqlsql-optimization

Has anyone ever successfully make index merge work for MySQL?


Setup:

mysql> create table t(a integer unsigned,b integer unsigned);
mysql> insert into t(a,b) values (1,2),(1,3),(2,4);
mysql> create index i_t_a on t(a);
mysql> create index i_t_b on t(b);
mysql> explain select * from t where a=1 or b=4;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t     | ALL  | i_t_a,i_t_b   | NULL | NULL    | NULL |    3 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

Is there something I'm missing?

Update

mysql> explain select * from t where a=1 or b=4;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t     | ALL  | i_t_a,i_t_b   | NULL | NULL    | NULL | 1863 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

Version:

mysql> select version();
+----------------------+
| version()            |
+----------------------+
| 5.1.36-community-log |
+----------------------+

Has anyone ever successfully make index merge work for MySQL?

I'll be glad to see successful stories here:)


Solution

  • Long back:

    show indexes from lesssong;

    Table, Non_unique, Key_name, Seq_in_index, Column_name, Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment
    'lesssong', 0, 'PRIMARY', 1, 'S_ID', 'A', 50000, , '', '', 'BTREE', ''
    'lesssong', 1, 'idx_s_name', 1, 'S_NAME', 'A', 25000, 10, '', '', 'BTREE', ''
    'lesssong', 1, 'idx_S_ARID', 1, 'S_ARID', 'A', 1315, , '', '', 'BTREE', ''
    'lesssong', 1, 'idxFTS', 1, 'S_NAME', '', 1, , '', '', 'FULLTEXT', ''
    

    Count = 50000

    explain select * from lesssong where s_name='kv' or s_arid=4

    1, 'SIMPLE', 'lesssong', 'index_merge', 'idx_s_name,idx_S_ARID,idxFTS', 'idx_s_name,idx_S_ARID', '12,4', '', 2, 'Using sort_union(idx_s_name,idx_S_ARID); Using where'
    

    Structure:

    'S_ID', 'int(10) unsigned', 'NO', 'PRI', '', 'auto_increment'
    'S_ALID', 'int(10) unsigned', 'NO', '', '', ''
    'S_ARID', 'int(10) unsigned', 'NO', 'MUL', '', ''
    'S_NAME', 'varchar(100)', 'NO', 'MUL', '', ''
    'S_LYRIC', 'text', 'NO', '', '', ''
    'S_WRITER', 'varchar(45)', 'NO', '', '', ''
    'S_LINK', 'varchar(255)', 'NO', '', '', ''
    

    Even for you structure I got it work for me:

    I added random 100 values:

    insert into t(a,b) select ceil(rand()*5),ceil(rand()*30)
    

    explain select * from t where a=1 or b=4;

    id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
    1, 'SIMPLE', 't', 'index_merge', 'i_t_a,i_t_b', 'i_t_a,i_t_b', '5,5', '', 32, 'Using union(i_t_a,i_t_b); Using where'