是否应该使用 USE/FORCE INDEX 更改 MySQL 查询中的 EXPLAIN 输出?

Posted

技术标签:

【中文标题】是否应该使用 USE/FORCE INDEX 更改 MySQL 查询中的 EXPLAIN 输出?【英文标题】:Should using USE/FORCE INDEX change the EXPLAIN output in a MySQL query? 【发布时间】:2020-02-24 04:25:17 【问题描述】:

如标题所示,在查询中明确使用FORCE INDEX (index_1, index_2) 后,EXPLAIN 输出是否会发生变化?

例如,我有以下查询:

select
    person_id,
    role_id,
    scope_id,
    count(distinct qualification_id) as ncomps
from dw_rolepersonqualification
where ((mandatory = 'y') and (expiry_date > now()))
group by 1, 2, 3

当我使用EXPLAIN 运行它时,我得到:

id: 1
select_type: SIMPLE
table: dw_rolepersonqualification
type: ALL
possible_keys: PRIMARY, idx_person, idx_role, idx_qualification, idx_scope, idx_mandatory
key: null
key_len: null
ref: null
rows: 8267852
Extra: Using where; Using filesort

当我添加FORCE INDEX (dx_person, idx_role, idx_qualification, idx_scope) 时,它不会改变EXPLAIN 的输出。这是意料之中的还是我错过了什么?

【问题讨论】:

请提供SHOW CREATE TABLE;我们需要查看索引的定义以及数据类型,以便在此处为您提供帮助。 @RickJames 我实际上并不是在请求优化提示,我只是想知道使用 FORCE INDEX 是否应该更改 EXPLAIN 输出。 【参考方案1】:

该查询的最佳索引是

INDEX(mandatory,  -- tested with "=", so first
      expiry_date)  -- a range

即便如此,它也可能认为索引不值得努力。如果优化器估计超过 ~20% 的表与 WHERE 子句匹配,它将决定扫描表而不是在索引的 BTree 和数据 BTree 之间跳转。

“覆盖”索引可能(或可能不会)更好:

INDEX(mandatory,  -- tested with "=", so first
      expiry_date,  -- a range
      person_id, role_id, scope_id,
            qualification_id) -- all other touched columns (any order)

(警告:我所说的某些内容可能无效;请提供SHOW CREATE TABLE。)

我的口头禅:“力量指数今天可能有用,但明天会伤害。”

【讨论】:

以上是关于是否应该使用 USE/FORCE INDEX 更改 MySQL 查询中的 EXPLAIN 输出?的主要内容,如果未能解决你的问题,请参考以下文章

在phonegap中以编程方式更改页面

是否应该在每次页面更改时验证令牌?

如果我在$ broadcast上更改变量,$ watch是否应该工作

谷歌地图:如何更改标记的 z-index?

如何在 Firefox OS 中制作服务应用程序?

是否应该在更改数据库的操作发生之前完成断言或检查?