我创建了一个索引
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'
);
解释输出
注意第1行
答案 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.user
,p.archived
等)。
查询也很重要的列的顺序。
尝试仅过滤startAt
和endAt
列。
https://use-the-index-luke.com/sql/where-clause/the-equals-operator/concatenated-keys
答案 2 :(得分:0)
MySQL在多列索引上有很好的documentation。
你的问题的答案是你在这两个领域使用了不平等。因此,MySQL会在查询中评估条件,并与索引中的列(按顺序)进行比较。第一列是startTime
,它有一个不等式比较。因此,MySQL从不比较第二列。
这个问题是关于为什么特定查询没有使用特定索引,并且已经多次回答。
目前尚不清楚查询的最佳方法是什么。我建议您提出另一个问题,提供示例数据,所需结果以及您的查询正在执行的操作的说明。