【问题标题】:mysql IN clause not using possible keysmysql IN子句不使用可能的键
【发布时间】:2013-01-22 18:42:41
【问题描述】:

我有一个相当简单的 mysql 查询,其中包含一些内部连接,然后是 where 子句。我已经为连接中使用的所有列以及主键创建了索引。我还有一个包含 IN 运算符的 where 子句。当只有 5 个或更少的 id 被传递到 IN 子句时,查询优化器使用我的索引之一在合理的时间内运行查询。当我使用解释时,我看到类型是范围,键是 PRIMARY。我的问题是,如果我在 IN 子句中使用超过 5 个 id,优化器会忽略所有可用的索引并且查询运行速度非常慢。当我使用解释时,我看到类型是 ALL,键是 NULL。

有人可以解释一下这里发生了什么以及我该如何解决这个问题。

谢谢

【问题讨论】:

  • 你能展示你到目前为止尝试过的东西吗=)可能是你的表模式和查询..
  • 当您使用多个 OR 语句而不是 IN 时,是否也会发生这种情况?
  • @Mt.Schneiders 是的!当我用 OR 替换 IN 时,它的行为完全相同。
  • 很奇怪。什么是表引擎? MyISAM 还是 InnoDB?此外,您是否尝试过“ANALIZE TABLE”命令?

标签: mysql query-optimization sql-execution-plan


【解决方案1】:

不管表上的“主键”索引如何优化 JOIN,您还应该有一个基于您应用 WHERE 的通用标准的索引。您的查询列需要更多信息,但您也应该对 WHERE 条件有一个索引。

【讨论】:

    【解决方案2】:

    您也可以尝试使用 Mysql 索引提示。它允许您指定在查询执行期间应使用哪个索引。

    例子:

     SELECT * FROM table1 USE INDEX (col1_index,col2_index)
      WHERE col1=1 AND col2=2 AND col3=3;
    

    -

    SELECT * FROM table1 IGNORE INDEX (col3_index)
      WHERE col1=1 AND col2=2 AND col3=3;
    

    更多信息在这里: Mysql Index Hints

    【讨论】:

      【解决方案3】:

      在检查我遇到的类似问题时发现了这一点。认为我的发现可能会对将来遇到类似问题的其他人有所帮助。

      我有一个大约 30 行的 MyISAM 表(包含类似单词的常见拼写错误,用于搜索,其中可能的原始拼写错误和替代单词都可能是有效的拼写,表格的大小会慢慢增加)。然而,对我来说,截止日期是如果 IN 子句中有 4 个项目,则使用索引,但当 IN 子句中有 5 个项目时,索引将被忽略(注意我没有尝试过替代词,所以 IN 子句中的实际单个项目可能是一个因素)。与 OP 非常相似,但字数不同。

      使用索引 不起作用,索引仍然会被忽略。 强制索引 确实有效,但我宁愿避免指定索引(以防有人删除索引)。

      对于一些测试,我用额外的 1000 个随机唯一行填充了表,即使 IN 子句中有 80 个项目,查询也会使用相关索引。

      因此,MySQL 似乎根据 IN 子句中的项目数与表中的行数相比来决定是否使用索引(但可能还有其他一些因素在起作用)。

      【讨论】:

        猜你喜欢
        • 2012-05-15
        • 2012-08-01
        • 1970-01-01
        • 2011-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-09
        • 1970-01-01
        相关资源
        最近更新 更多