SQL查询应该能工作1毫秒,但它能在5分钟内完成任务

SQL查询应该能工作1毫秒,但它能在5分钟内完成任务,sql,Sql,需要帮助才能快速工作,有可能吗?我的头准备爆炸,试图理解它应该做什么。表中有~5k条记录 该查询的描述是:查看是否存在拨号事件,之后是网桥事件,但没有取消链接事件。尝试使用连接而不是exists SELECT t1.* FROM asterisk t1 WHERE EXISTS (SELECT * FROM asterisk t2 WHERE t2.id <>

需要帮助才能快速工作,有可能吗?我的头准备爆炸,试图理解它应该做什么。表中有~5k条记录
该查询的描述是:查看是否存在拨号事件,之后是网桥事件,但没有取消链接事件。

尝试使用连接而不是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