所以我有这个问题:
EXPLAIN SELECT SQL_CALC_FOUND_ROWS
u.userid,
u.firstname,
u.lastname,
u.job_title,
u.email,
u.org_id
FROM piltools.users u
WHERE
u.org_id = 'VX3'
AND (
u.firstname LIKE 'Chris%'
OR u.lastname LIKE 'Chris%'
OR CONCAT(u.firstname, ' ', u.lastname) LIKE 'Chris%'
OR u.email LIKE 'Chris%'
)
AND u.firstname !=''
AND u.lastname !=''
AND u.deleted = '0'
每个列都有一个索引,我为删除的org_id,lastname,firstname,job_title,email,userid创建了一个CUSTOM索引,特别是对于这个查询,但是当我运行解释它时说:
id 1
select_type SIMPLE
表你
输入参考
possible_keys 电子邮件,名字,姓氏,org_id,已删除,CUSTOM
键 org_id
key_len 17
参考 const
行 113967
额外使用
为什么它使用单独的org_id索引而不是我的CUSTOM索引包含它需要的所有字段?
答案 0 :(得分:1)
优化器会尝试使用每个“可能的索引”来评估处理查询所需的时间,然后实际使用它假定允许最快执行的那个。
现在,为什么它决定不使用您精心定制的索引,如果不知道您的数据配置文件就无法确定,但是:
索引只能用于在声明中按其出现顺序过滤列。要使用CUSTOM
索引,首先它必须按deleted
过滤记录(好,这个是WHERE
子句的标准),然后是org_id
(也是你的一部分)过滤器),然后是lastname
,依此类推。
表中的大多数记录可能与条件WHERE deleted = 0
匹配,因此首先对此字段进行过滤的好处被视为“低”
那么使用org_id
过滤CUSTOM
的好处等于仅使用org_id
上的索引带来的好处
然后在条件lastname !=''
上过滤的好处被认为是“低”,因为(可能)您的大多数记录都符合此条件
条件lastname LIKE 'Chris%'
的过滤优势因其作为OR
运算符
与firstname LIKE 'Chris%'
其余的索引列仅用于过滤
您的CUSTOM
索引很大,因为它主要包含字符串列。优化者可能会认为加载此指数的成本与其可能的收益相比过高
您可以通过添加FORCE INDEX
子句来诱使优化器使用您的索引(而不是强制,如关键词所示)。
但优化器通常知道的更好。如果它选择不使用它,我会相信这个决定。只有(org_id, deleted)
上的索引,按此顺序,或者(org_id, deleted, lastname, firstname)
,您可能会获得更好(更快)的结果。