【问题标题】:MySQL. Creating an index for "OR" queriesmysql。为“OR”查询创建索引
【发布时间】: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)。我创建了以下索引:BACDCABC

使用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, [Collat​​ion] = > 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 :)

标签: mysql indexing explain


【解决方案1】:

由于 SQL 语句中的OR,MySQL 只是获取包含A 的第一个索引,即ACD

我得出的结论是,使用INDEX 解决此问题的方法是进行两个单独的查询。 SELECT A,B,C,D,E FROM table WHERE A=23 AND B=45 将使用INDEX ABC,然后SELECT A,B,C,D,E FROM table WHERE A=23 AND C=43 将使用INDEX ACD。这一切都可以通过(...) UNION (...) 一步完成,结果证明它更快并且只使用 INDEX。

【讨论】:

    【解决方案2】:

    Mysql 只能使用复合索引的“最左边”部分。即,如果你的 where 子句看起来像

    WHERE A=1 AND B=2
    

    那么 MySQL 可以在 AAB 上使用索引,但最好使用 ABACB 无法使用,因为索引被另一列拆分

    对于您给定的 WHERE 子句,我认为 MySQL 查询引擎不能利用多个索引。我会制作一个ABAC 并使用 FORCE INDEX,看看哪个更快。

    在这种情况下,当您查找 A 和另一列时,三列复合键将无济于事。如果您的查询使用AND 而不是OR,这种键会有所帮助。 ABC 上的索引将有助于

    WHERE A=1 AND B=2 AND C=3
    

    【讨论】:

    • 是的,AND 按预期使用 ABC 查询。正如@Daan 在之前的评论中提到的,使用AABAC 将是多余的。来自 MySQL 文档:“优化器可以使用索引的任何最左边的前缀来查找行。INDEX on (col1, col2, col3),您在 (col1)、(col1, col2) 上具有索引搜索功能,并且(col1, col2, col3)。”
    • 这是一个关于 OR,而不是 AND 的问题。
    猜你喜欢
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 2021-05-29
    相关资源
    最近更新 更多