【问题标题】:MySQL Index is NULL but there are available KeysMySQL 索引为 NULL,但有可用的键
【发布时间】:2018-08-02 17:55:39
【问题描述】:

我在运行 mysql 查询时遇到以下问题: 查询非常慢,当我使用解释查询键为空但可能键可用且顺序正确时,我还尝试为每行添加独立索引,但键仍然为空。

可以在这里查看表、索引和mysql的解释:https://snag.gy/vcChl6.jpg

【问题讨论】:

    标签: mysql performance indexing


    【解决方案1】:

    优化器可能刚刚决定没有理由使用索引。

    由于您使用的是SELECT *,这意味着如果它使用索引,那么它必须使用索引中的主键然后返回并从聚集索引中查找所有必要的数据。这称为双重查找,通常不利于性能。由于该表中的记录太少,优化器可能决定改为轻松地进行全表扫描并更快地获得结果。

    简而言之,这是预期的行为。

    如果您只想SELECT 一些列,请将它们添加到t1 索引中,然后仅将SELECT 添加到您需要的列中,并使用给定的WHERE 子句。它应该使用索引。随着表的大小增加,它也可能开始使用索引,一旦它估计双重查找比全表扫描便宜。

    【讨论】:

    • 感谢您的回答,这可能是因为我尝试了其他所有方法来让 mysql 使用它,我只是在数据库更大并且我想预先优化它时做准备。跨度>
    【解决方案2】:

    猜测:大多数行属于那个“项目”和那个“语言”。

    优化器不理解这个事实,所以它采用显然是最好的索引:

    (id_project, id_lang)
    

    这个也不错:(id_lang, id_project)

    不公平...EXPLAIN 提到了名为 id_project 和 id_lang 的索引(没用),但索引列表显示了一个复合索引 t1(id_project, id_lang)(有用)。

    然后,正如 Willem 所建议的,它必须在索引和表之间反弹。通常(也就是说,当它有足够的统计信息时),优化器会说“哦,超过 ~20% 的表被引用;让我们忽略任何索引。”

    你可以做的事情:

    • 去掉那个索引。
    • * 更改为仅包含您需要的列的列表。特别是,如果您避免使用 3 个 TEXT 列,则会启动两个优化。或者,任何永远不会超过 255 个字符的列都可以更改为 VARCHAR(255)
    • 使用其他一些过滤、排序、限制等。如果这是一个 Web 应用程序,您真的想要获得 ~534 行吗?

    【讨论】:

      猜你喜欢
      • 2013-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-16
      • 2012-04-29
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      相关资源
      最近更新 更多