【问题标题】:Why MySql doesn't use my index and how to avoid the "Using temporary; Using filesort"?为什么 MySql 不使用我的索引以及如何避免“使用临时;使用文件排序”?
【发布时间】:2023-03-18 05:25:01
【问题描述】:

我有一个如下所示的 MySql 查询:

SELECT trace_access.Employe_Code, trace_access.Employe_Prenom, 
trace_access.Employe_Nom, , trace_access.Evenement_Date, trace_access.Evenement_Heure
FROM trace_access 
INNER JOIN emp
ON trace_access.Employe_Code = emp.Employe_CodeEmploye
LEFT JOIN user
ON emp.Employe_ID = user.Employe_ID
LEFT JOIN role 
ON role.User_ID = user.User_ID
WHERE trace_access.Employe_Nom Not Like "TEST%NU" 
ORDER BY trace_access.Evenement_Date DESC , trace_access.Evenement_Heure DESC

“trace_access”表包含近 2000 万个条目。

当我解释查询时:

explain query

我的问题是为什么 MySql 没有使用 emp 表的键以及如何避免“使用临时;使用文件排序”??

我曾试图强迫它使用我的索引,但没有奏效。 查询持续一小时以上,在/tmp文件夹中写入超过8Go的文件!!!

有什么帮助吗?

非常感谢。

【问题讨论】:

  • 我怀疑基于 NOT 的条件是否会使用索引,当它是 LIKE 时更糟。但是像这样的简单 Select 不应该只在 2000 万行上运行一个小时。返回多少行?
  • 发生了一些奇怪的事情。请为表格提供SHOW CREATE TABLE;我怀疑数据类型不一致。
  • 查询中有多余的逗号','。这是您实际运行的查询吗?

标签: mysql sql performance indexing sql-order-by


【解决方案1】:

根据您当前的执行计划(从emp 开始),需要进行全表扫描,并且emp 上没有有用的索引。当您在 jointrace_access 之后仅获得相对少量的行时,这可能是有意义的,这可能不是这里的情况。

为了防止filesort,您需要一个支持您的order by 的索引。所以添加,如果它还不存在,索引trace_access(Evenement_Date, Evenement_Heure)

这可能已经足以让 MySQL 以 trace_access 开头。如果不是,请将INNER JOIN emp 替换为STRAIGHT_JOIN emp。这将迫使 MySQL 这样做。

还为emp(Employe_CodeEmploye) 添加索引。

根据您的数据,您可以尝试将Employe_Code 和/或Employe_Nom 作为第3 和/或第4 列添加到trace_access 的索引中,尽管它可能不会产生太大影响。

【讨论】:

    猜你喜欢
    • 2021-11-11
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 2012-05-23
    • 2016-09-04
    相关资源
    最近更新 更多