为什么即使我在查询中使用了所有索引列,也没有使用多列索引?

g6ll5ycj  于 2021-06-24  发布在  Mysql
关注(0)|答案(3)|浏览(251)

我创建了一个索引

CREATE INDEX idx_prog_time ON program (startTime, endTime);

但在我的问题中,即使我有 WHERE 两边都有 startTime 以及 endTime ,似乎没有使用索引(索引显示在可能的键中,但不是键)?

EXPLAIN SELECT prog.id
FROM program prog
WHERE prog.asset IN (
    SELECT DISTINCT(a.id)
    FROM asset a
    INNER JOIN assetpackage ap
    ON ap.asset = a.id
    INNER JOIN package p
    ON p.id = ap.package
    INNER JOIN component c
    ON c.package = p.id
    INNER JOIN provision pr
    ON pr.component = c.id
    INNER JOIN transaction t
    ON pr.transaction = t.id
    WHERE prog.startTime < '2018-04-24 17:30:00'
    AND prog.endTime > '2018-04-24 17:30:00'
    AND p.archived = 0
    AND p.serviceNo IS NOT NULL
    AND t.user = 111
    AND pr.startAt < '2018-04-24 17:30:00'
    AND pr.endAt > '2018-04-24 17:30:00'
);

解释输出

注意第一排

vsnjm48y

vsnjm48y1#

因为还有其他列(如 t.user , p.archived 等)以及索引列之前的where条件。
查询也很重要的列的顺序。
仅尝试筛选 startAt 以及 endAt 列。
https://use-the-index-luke.com/sql/where-clause/the-equals-operator/concatenated-keys

nwlqm0z1

nwlqm0z12#

mysql有很好的多列索引文档。
你的问题的答案是,你在这两个领域使用不等式。因此,mysql评估查询中的条件,并与索引中的列(按顺序)进行比较。第一列是 startTime 它有一个不平等的比较。因此,mysql从不比较第二列。
这个问题是关于为什么一个特定的查询不使用特定的索引,这个问题已经被回答了多次。
目前还不清楚什么是最好的查询方法。我建议您再问一个问题,提供示例数据、所需结果,并解释您的查询正在做什么。

qq24tv8q

qq24tv8q3#

可以使用内部联接而不是in子句

SELECT prog.id
FROM program prog
INNER JOIN (
    SELECT a.id  as my_id
    FROM asset a
    INNER JOIN assetpackage ap
    ON ap.asset = a.id
    INNER JOIN package p
    ON p.id = ap.package
    INNER JOIN component c
    ON c.package = p.id
    INNER JOIN provision pr
    ON pr.component = c.id
    INNER JOIN transaction t
    ON pr.transaction = t.id
    AND p.archived = 0
    AND p.serviceNo IS NOT NULL
    AND t.user = 111
    AND pr.startAt < '2018-04-24 17:30:00'
    AND pr.endAt > '2018-04-24 17:30:00'
) T on T.my_id = prog.asset 
WHERE prog.startTime < '2018-04-24 17:30:00'
  AND prog.endTime > '2018-04-24 17:30:00'

相关问题