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

时间:2018-04-24 09:44:59

标签: mysql sql

我创建了一个索引

CREATE INDEX idx_prog_time ON program (startTime, endTime);

但在我的查询中,即使WHEREstartTime上都有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'
);

解释输出

enter image description here

注意第1行

3 个答案:

答案 0 :(得分:0)

您可以使用内部联接而不是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'

答案 1 :(得分:0)

因为在索引列之前的where条件中还有其他列(例如t.userp.archived等)。

查询也很重要的列的顺序。

尝试仅过滤startAtendAt列。

https://use-the-index-luke.com/sql/where-clause/the-equals-operator/concatenated-keys

答案 2 :(得分:0)

MySQL在多列索引上有很好的documentation

你的问题的答案是你在这两个领域使用了不平等。因此,MySQL会在查询中评估条件,并与索引中的列(按顺序)进行比较。第一列是startTime,它有一个不等式比较。因此,MySQL从不比较第二列。

这个问题是关于为什么特定查询没有使用特定索引,并且已经多次回答。

目前尚不清楚查询的最佳方法是什么。我建议您提出另一个问题,提供示例数据,所需结果以及您的查询正在执行的操作的说明。