我正在尝试运行此sql查询:
SELECT
a.ticketnumber
FROM
ticket_updates a
LEFT JOIN
ticket_updates b
ON
b.ticketnumber = a.sequence AND b.type = 'reminder_complete'
WHERE
b.ticketnumber IS NULL AND
(a.type = 'reminder' OR a.type = 'reminder_high') AND
(a.for_agent = '' OR a.for_agent = '2') AND
a.notes <= '2018-05-10 23:00:00' AND
a.ticketnumber NOT IN (
SELECT ticketnumber
FROM ticket_updates
WHERE
type = 'reminder_complete' AND
ticketnumber = a.ticketnumber)
但由于某些原因,返回任何结果需要14.8126秒。
测试时,它返回1行,我不明白为什么它这么慢。我相信这可能与连接有关,但我希望有人能帮助我,并指出正确的方向请?
我很抱歉,如果我错过了任何信息,所以请原谅我的无知。
2条答案
按热度按时间dvtswwa31#
使用
EXPLAIN
看看执行计划。查询已在对使用反联接模式
b
.我建议使用相同的反连接模式来代替
NOT IN
检查(反连接的大驼峰似乎让我们的大脑被它包围了;一旦我们了解了这个模式,我们就应该能够利用它。像这样:
就性能而言,我们需要确保有合适的索引可用。
考虑到
NOT IN (correlated subquery)
是对执行时间的贡献,用反连接代替它使mysql更有可能使用合适的索引(如果有)(就性能而言,如果我们不小心的话,那些相关子查询的重复执行将吃掉我们的午餐,也会吃掉我们的午餐盒。)再次,使用
EXPLAIN
看看执行计划。反连接模式可以替换为
NOT EXISTS
得到一个同等的计划(与直觉相反,反连接模式有时会在explain输出的额外列中显示“not exists”,其中not exists不存在。)我预计这将给出一个几乎相等的执行计划:
ubby3x7f2#
除了其他答案,您还需要以下索引:
它可能有助于结合
LEFT JOIN
以及NOT IN
: