1

所以我有这个查询:

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 创建了一个自定义索引,特别是针对此查询,但是当我运行解释时,它说:

编号1

选择类型简单

类型参考

possible_keys电子邮件、名字、姓氏、org_id、已删除、自定义

关键org_id

key_len 17

参考常量

113967

额外的使用 where

为什么它使用单独的 org_id 索引而不是我的 CUSTOM 索引,它具有它需要的所有字段?

4

1 回答 1

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).

于 2013-06-19T22:47:02.123 回答