4

设置:

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 |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

有什么我想念的吗?

更新

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 |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

版本

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

有没有人成功地使索引合并为 MySQL 工作?

我很高兴在这里看到成功的故事:)

4

3 回答 3

4

我不知道这是否是真正的原因,但我认为任何值得一提的 DBMS 都会看到“rows = 3”属性,并认为它甚至不值得查看索引。您可以对三行进行全表扫描的速度将使任何其他方法都没有实际意义。

尝试用几千行做同样的事情,看看你是否得到相同的结果。


这里,评论者说“我测试的表导致索引合并联合版本在某些情况下不使用任何索引”尽管他们似乎不知道这些情况是什么,确切地说:-)这可能是什么您也可以向 MySQL 支持小组(和开发人员)提出建议。

只是出于兴趣,以下查询从 EXPLAIN 中为您提供了什么:

select * from t where a=1
union
select * from t where b=4;

并且可能是 MySQL 正在根据表本身的数据评估是否使用索引联合。如果只有 2 个变体a和 3 个变体b,它可能会再次决定您的查询无论如何都会返回大部分行,因此不必为优化而烦恼。

您可以尝试在和列中同时使用大量行多种值。ab

请记住,这不是基于我对 MySQL 的了解,我从未见过代码库或使用过该产品。但是,我在某个主流数据库产品做了一些工作 - 所以这个建议是基于我对高效做事的理解,这可能不是 MySQL 具体的情况,实际上可能根本不是这样:-)

于 2010-03-25T03:44:04.307 回答
2

长背:

显示来自lessong的索引;

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', ''

计数 = 50000

解释 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'

结构:

'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', '', '', ''

即使对于您的结构,我也可以为我工作:

我添加了随机 100 个值:

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

解释 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'
于 2010-04-05T08:50:41.867 回答
0

太糟糕了,没有办法强制 MySQL 使用合并,比如当它默认选择错误的索引时如何强制它使用特定的索引(很少发生,但我已经看到它并且不得不处理它) .

我猜这仅仅是因为您的数据没有足够的基数让 MySQL 决定值得花时间使用索引,更不用说 index_merge。1800 行算不了什么 - 真的。创建至少一百万行,并使每一行都独一无二。然后它可能会做你想要的。对于这么小的表,索引并不能真正为您做任何事情。

于 2010-04-07T19:18:29.393 回答