SQL查询应该能工作1毫秒,但它能在5分钟内完成任务
需要帮助才能快速工作,有可能吗?我的头准备爆炸,试图理解它应该做什么。表中有~5k条记录SQL查询应该能工作1毫秒,但它能在5分钟内完成任务,sql,Sql,需要帮助才能快速工作,有可能吗?我的头准备爆炸,试图理解它应该做什么。表中有~5k条记录 该查询的描述是:查看是否存在拨号事件,之后是网桥事件,但没有取消链接事件。尝试使用连接而不是exists SELECT t1.* FROM asterisk t1 WHERE EXISTS (SELECT * FROM asterisk t2 WHERE t2.id <>
该查询的描述是:查看是否存在拨号事件,之后是网桥事件,但没有取消链接事件。尝试使用连接而不是exists
SELECT t1.*
FROM asterisk t1
WHERE EXISTS (SELECT * FROM asterisk t2
WHERE t2.id <> t1.id
AND t2.unique_id = t1.unique_id
AND t1.operator_dial = '203'
AND t1.event = 'Dial'
AND t2.event = 'Bridge'
AND NOT EXISTS (SELECT * FROM asterisk t3
WHERE t3.id <> t1.id
AND t2.unique_id = t3.unique_id
AND t1.operator_dial = '203'
AND t3.event = 'Unlink'))
ORDER BY date DESC
LIMIT 1
另外,请查看,看看是什么导致查询耗时如此之长,并确认正在使用索引。如果我没有遗漏什么,您的查询应该如下所示:
SELECT t1 *
FROM asterisk t1
INNER JOIN asterisk t2 on t1.id=t2.id
AND t2.unique_id = t1.unique_id
AND t1.operator_dial = '203'
AND t1.event = 'Dial'
AND t2.event = 'Bridge'
LEFT OUTER JOIN asterisk t3 on t2.unique_id=t3.unique_id
AND t3.id <> t1.id
AND t1.operator_dial = '203'
AND t3.event = 'Unlink'
WHERE t3.id IS NULL
ORDER BY date DESC
LIMIT 1
但是,如果您在操作员拨号盘和事件以及日期上有索引,这将对性能有很大帮助
select t1.*
from asterisk as t1
where
t1.operator_dial = '203' and
t1.event = 'Dial' and
exists (
select *
from asterisk as t2
where
t2.id <> t1.id and t2.unique_id = t1.unique_id
t2.event = 'Bridge' and t2.date > t1.date
) and
not exists
(
select *
from asterisk as t3
where
t3.id <> t1.id and t3.unique_id = t1.unique_id and
t3.event = 'Unlink' and t3.date > t1.date
)
order by t1.date desc
limit 1
注意,我省略了t1.id t2.id。event和date子句将隐式强制执行此条件
查看是否有拨号事件,之后是桥接事件,但没有取消链接事件
我假设没有取消链接事件意味着根本没有,尽管您的需求可以理解为拨号事件之后没有发生取消链接事件。如果是后一种情况,您可以将t3.date>t1.date添加到联接中以更改功能。您的表有索引?相关子查询的性能不太好。尝试左连接。限制1和顺序BY在速度方面倾向于相互抵消。您仍然需要仔细检查所有内容才能找到最上面的记录。为什么您认为查询应该在1毫秒内得到回答?你认为这是有可能的吗?看看是否有拨号事件,之后是桥接事件,但没有链接事件。请在查询中没有看到任何保证事件排序的尝试后进行定义。应该在t1.idt2.id上执行外部连接星号t2,我认为您可以这样做。对于t2.id和t3.id也是一样,至少从OP的代码来看,我是这么想的。我的错误@cars10是正确的。@Malachi t2和t3的内部连接将杀死我们正在寻找的行。强调添加:查看是否有拨号事件,之后是桥接事件。这里不能保证桥接事件发生在拨号事件之后。然而,问题的查询也没有满足这个条件。Emphasis补充道:看看是否有拨号事件,之后是桥接事件。这里不能保证桥接事件发生在拨号事件之后。但是,问题的查询也不满足此条件。缺少该描述
SELECT t1.*
FROM Asterisk t1
INNER JOIN Asterisk t2
ON t1.unique_id = t2.unique_id
AND t2.date > t1.date
AND t2.event = 'Bridge'
LEFT JOIN Asterisk t3
ON t1.unique_id = t3.unique_id
AND t3.event = 'Unlink'
WHERE t1.operator_dial = '203'
AND t1.event = 'Dial'
AND t3.id IS NULL
ORDER BY t1.date
LIMIT 1