如何解决SQL 查询在数据库服务器上运行缓慢
执行计划是attached
SELECT a.*,k.UserPrivileges,k.Type
FROM NotifyInterests2 a,KUAF k
WHERE a.UserID = k.ID
AND EXISTS (SELECT ID FROM KUAF WHERE a.UserID = ID AND NOT Type IN (1,2,4))
AND (a.NodeID IN ( SELECT 0 UNION ALL ( SELECT DISTINCT( -1 * ID )
FROM KUAF WHERE Type = 5 ) UNION ALL ( SELECT DISTINCT AncestorID
FROM DTreeAncestors
WHERE Exists ( SELECT EventInt2 FROM LLEventQueue
WHERE EventHandlerID = 9001 AND EventSeqNo <=45075882 AND EventInt2 = DataID
UNION ALL SELECT EventInt2 * -1 FROM LLEventQueue
WHERE EventHandlerID = 9001
AND EventSeqNo <=45075882 AND EventInt2 = DataID ))))
解决方法
这就是查询 =) 提示:尝试将代码的各个部分“分组”以提高可读性;它会让你的生活轻松 100 倍;现在,当你写这个的时候,甚至在你维护这个的时候,甚至更多 =)
仍有一些问题:
- 什么叫“慢”?
- 每个表中有多少条记录?
- 查询返回了多少条记录?
- 表上的索引是什么? (sp_helpindex)
此外,查看整个查询计划可能会有所帮助,但立即突出的一件事是 KEAF 似乎没有聚集索引。我认为它因此也缺少主键?由于您在那里有一个字段 ID,我希望它可以唯一标识每条记录?如果是,则向表中添加一个 PK 并检查这对整个查询有何影响。
为了可读性,我试图重新安排一些东西,最后我得到了下面的结果。我对一些别名进行了赌注,因为它们在原始查询中缺失。
SELECT a.*,k.UserPrivileges,k.Type
FROM NotifyInterests2 a
JOIN KUAF k
ON k.ID = a.UserID
WHERE EXISTS ( SELECT kx.ID
FROM KUAF kx
WHERE kx.ID = a.UserID
AND NOT kx.Type IN (1,2,4) )
AND a.NodeID IN ( SELECT 0
UNION ALL
SELECT DISTINCT( -1 * k5.ID )
FROM KUAF k5
WHERE k5.Type = 5
UNION ALL
SELECT DISTINCT da.AncestorID
FROM DTreeAncestors da
WHERE EXISTS ( SELECT l1.EventInt2
FROM LLEventQueue l1
WHERE l1.EventHandlerID = 9001
AND l1.EventSeqNo <= 45075882
AND l1.EventInt2 = da.DataID
UNION ALL
SELECT l2.EventInt2 * -1
FROM LLEventQueue l2
WHERE l2.EventHandlerID = 9001
AND l2.EventSeqNo <= 45075882
AND l2.EventInt2 = da.DataID )
)
我认为有些部分可以简化。 这真的没有意义:
SELECT DISTINCT da.AncestorID
FROM DTreeAncestors da
WHERE EXISTS ( SELECT l1.EventInt2
FROM LLEventQueue l1
WHERE l1.EventHandlerID = 9001
AND l1.EventSeqNo <= 45075882
AND l1.EventInt2 = da.DataID
UNION ALL
SELECT l2.EventInt2 * -1
FROM LLEventQueue l2
WHERE l2.EventHandlerID = 9001
AND l2.EventSeqNo <= 45075882
AND l2.EventInt2 = da.DataID )
您只是在 WHERE EXISTS()
部分执行了两次相同的查询。
此外,由于这部分属于 WHERE IN (...)
结构,因此实际上并不需要 DISTINCT
。事实上,将其转换为 WHERE EXISTS()
构造可能更容易。像这样:
AND ( a.NodeID = 0
OR EXISTS (SELECT *
FROM KUAF k5
WHERE k5.Type = 5
AND ( -1 * k5.ID ) = a.node_id)
OR EXISTS ( SELECT *
FROM DTreeAncestors da
WHERE da.AncestorID = a.NodeID
AND EXISTS ( SELECT *
FROM LLEventQueue l1
WHERE l1.EventHandlerID = 9001
AND l1.EventSeqNo <= 45075882
AND l1.EventInt2 = da.DataID )
)
通常我不喜欢 OR
,但我认为在这种情况下它可能会奏效。
所以我最终得到:
SELECT a.*,k.Type
FROM NotifyInterests2 a
JOIN KUAF k
ON k.ID = a.UserID
WHERE EXISTS ( SELECT kx.ID
FROM KUAF kx
WHERE a.UserID = kx.ID
AND NOT kx.Type IN (1,4) )
AND ( a.NodeID = 0
OR EXISTS (SELECT *
FROM KUAF k5
WHERE k5.Type = 5
AND ( -1 * k5.ID ) = a.node_id)
OR EXISTS ( SELECT *
FROM DTreeAncestors da
WHERE da.AncestorID = a.NodeID
AND EXISTS ( SELECT *
FROM LLEventQueue l
WHERE l.EventHandlerID = 9001
AND l.EventSeqNo <= 45075882
AND l.EventInt2 = da.DataID )
)
)
试试这个并检查查询计划。如果它仍然太慢,我们需要查看定制表上的索引,看看我们可以在哪里优化它们。
,您没有提到表中是否存在以及哪些索引存在。 我会尝试创建以下索引,看看是否有任何性能提升:
CREATE INDEX kuaf_idx_id_type ON KUAF (ID,Type);
CREATE INDEX kuaf_idx_type ON KUAF (Type);
CREATE INDEX lleventqueue_idx_eventha_eventin_dataid_eventse ON LLEventQueue (EventHandlerID,EventInt2,DataID,EventSeqNo);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。