【问题标题】:Why isn't MySQL using the index I made for it?为什么 MySQL 不使用我为它创建的索引?
【发布时间】:2013-06-19 18:07:07
【问题描述】:

所以我有这个查询:

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

id 1

select_type简单

表格 u

类型参考

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

key org_id

key_len 17

ref 常量

113967

额外使用 where

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

【问题讨论】:

    标签: mysql indexing


    【解决方案1】:

    优化器尝试使用每个“可能的索引”来评估处理他的查询所需的时间,然后实际使用它认为可以最快执行的那个。

    现在,如果不知道您的数据配置文件,就无法确定为什么它决定不使用您精心定制的索引,但是:

    • 索引只能用于按列在声明中出现的顺序过滤。要使用CUSTOM 索引,首先它必须通过deleted 过滤记录(很好,这是WHERE 子句的一部分),然后是org_id(也是您的过滤器的一部分),然后是lastname,等等。

    • 您表中的大多数记录可能与条件WHERE deleted = 0 匹配,因此首先过滤此字段的好处被认为是“低”

    • 那么使用CUSTOM 过滤org_id 的好处等于仅使用org_id 上的索引的好处

    • 那么过滤条件lastname !='' 的好处被认为是“低”,因为(可能)您的大多数记录都满足此条件

    • 过滤条件 lastname LIKE 'Chris%' 的好处由于它是 OR 运算符的操作数而大大减轻了

    • 同上firstname LIKE 'Chris%'

    • 剩余的索引列不用于过滤

    • 您的CUSTOM 索引很大,因为它主要包含字符串列。优化器可能会假设加载此索引的成本与其可能的收益相比太高了

    您可以通过添加FORCE INDEX 子句来诱使优化器使用您的索引(而不是像关键字所暗示的那样强制它)。

    但优化器通常知道得更好。如果它选择不使用它,我会相信这个决定。仅在(org_id, deleted) 上按此顺序或(org_id, deleted, lastname, firstname) 上的索引可能会获得更好(更快)的结果。

    【讨论】:

      猜你喜欢
      • 2014-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多