是否应该使用 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 输出?的主要内容,如果未能解决你的问题,请参考以下文章