【发布时间】:2012-04-07 11:28:11
【问题描述】:
我有一个包含 200k 条目的表,其中包含 INT 列。我想创建一个索引以使查询更快。这是我要执行的查询:SELECT A,B,C,D,E FROM table WHERE A=23 and (B=45 or C=43)。我创建了以下索引:B、ACD、C、ABC。
使用EXPLAIN 命令我发现MySQL 选择了索引ACD。所以我不断用更多的值填充表,我意识到 MySQL 正在上面的索引之间切换(并不总是相同的)。
由于有许多插入,拥有各种索引会导致性能问题,我们可以假设该表被其他需要不同列的查询访问,每个索引都有意义。
我知道USE INDEX(),但我想了解我们是否应该信任 MySQL 来选择正确的索引。
【问题讨论】:
-
“我们可以假设该表被其他查询访问,这些查询需要每个索引都有意义的不同列”是什么意思?您能否举一些此类查询的示例?您能否也给我们
SHOW INDEXES FROM table查询的输出? A、AB 和 AC 上的索引肯定是多余的:这些索引已经分别被 ACD/ABC、ABC 和 ACD 上的索引覆盖。您可以在dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html 了解 MySQL 如何处理多列索引 -
查询示例:
GET B FROM table WHERE B=12。好的,我可以消除 A、AB、AC(谢谢)。但它仍然没有解释使用ACD的原因。当D甚至不在WHERE语句中时。 -
是的,这有点神秘:
SHOW INDEXES FROM table查询的输出可能有助于了解发生这种情况的原因:) -
显示索引 test_index_table [Table] => test_index_table, [Non_unique] => 0, [Key_name] => PRIMARY, [Seq_in_index] => 1, [Column_name] => ID, [Collation] = > A, [基数] => 100567, [Sub_part] => , [Packed] => , [Null] => , [Index_type] => BTREE, [Comment] =>.
-
我认为 UNION 选择可能是解决此问题的最快方法,正如您已经发现的那样。你也可以尝试
SELECT A,B,C,D,E FROM table WHERE (A=23 AND B=45) OR (A=23 AND C=43)。我不确定 MySQL 在选择索引方面会怎么想。我认为,但不确定,这可能会导致全表扫描......而且这种方法没有真正的好处,而不是使用 UNION,所以我建议你简单地使用 UNION :)