sql-server - 使用两个连接到同一个表的慢速执行 T-SQL 查询
问题描述
我正在努力弄清楚下面显示的 T-SQL 查询发生了什么。
您将看到同一个表的两个内部连接,尽管连接条件不同。第一个连接本身运行大约 21 秒,如果我自己运行第二个连接,它会在大约 27 秒内完成。
如果我将两个连接都保留在原位,则查询将运行并运行,直到我最终停止查询。适当的索引似乎已经到位,我知道这个查询在不同的环境中运行,马力较小,唯一的区别是另一台服务器正在运行 SQL Server 2012,而我正在运行 SQL Server 2016,尽管数据库处于 2012 兼容模式:
此连接在约 21 秒内运行。
SELECT
COUNT(*)
FROM
dbo.SPONSORSHIP as s
INNER JOIN
dbo.SPONSORSHIPTRANSACTION AS st
ON st.SPONSORSHIPCOMMITMENTID = s.SPONSORSHIPCOMMITMENTID
AND st.TRANSACTIONSEQUENCE = (SELECT MIN(TRANSACTIONSEQUENCE)
FROM dbo.SPONSORSHIPTRANSACTION AS ms
WHERE ms.SPONSORSHIPCOMMITMENTID = s.SPONSORSHIPCOMMITMENTID
AND ms.TARGETSPONSORSHIPID = s.ID)
此连接在约 27 秒内运行。
SELECT
COUNT(*)
FROM
dbo.SPONSORSHIP AS s
INNER JOIN
dbo.SPONSORSHIPTRANSACTION AS lt ON lt.SPONSORSHIPCOMMITMENTID = s.SPONSORSHIPCOMMITMENTID
AND lt.TRANSACTIONSEQUENCE = (SELECT MAX(TRANSACTIONSEQUENCE)
FROM dbo.SPONSORSHIPTRANSACTION AS ms
WHERE ms.SPONSORSHIPCOMMITMENTID = s.SPONSORSHIPCOMMITMENTID
AND s.ID IN (ms.CONTEXTSPONSORSHIPID,
ms.TARGETSPONSORSHIPID,
ms.DECLINEDSPONSORSHIPID)
AND ms.ACTIONCODE <> 9)
解决方案
这些都被认为是相关的子查询。您通常应该避免这种模式,因为它会导致所谓的“RBAR”......这是“Row by Agonizing Row”。在您专注于解决此特定查询之前,我建议您重新访问查询本身,看看您是否可以通过更基于集合的方法解决此问题。您会发现,在大多数情况下,您还有其他方法可以实现这一目标并显着降低成本。
举个例子:
select
total_count
,row_sequence
from
(
SELECT
total_count = COUNT(*)
,row_sequence = row_number() over(order by st.TRANSACTIONSEQUENCE asc)
FROM
dbo.SPONSORSHIP as s
INNER JOIN dbo.SPONSORSHIPTRANSACTION AS st
ON st.SPONSORSHIPCOMMITMENTID = s.SPONSORSHIPCOMMITMENTID
) as x
where
x.row_sequence = 1
这是一个未经测试的简单示例。为了将来参考,如果您想要最佳答案,最好生成一个可以使用的临时表或测试数据集,以便有人可以提供完整的工作示例。
我给出的示例显示了所谓的窗口函数。当您看到单词序列、需要组中的第一个/最后一个等等时,请仔细查看它们以帮助选择结果。
希望这能给你一些想法!欢迎来到堆栈溢出!
推荐阅读
- android - Android房间关系数据库
- reactjs - 面对无法获取项目时如何修复firebase部署反应应用程序问题
- vba - 请帮我解决案例操作员的问题
- jquery - 使用 migrate 插件将 jQuery v2.2.3 升级到 v3.6 的问题
- autodesk-forge - 在查看器 Autodesk Forge 中隐藏级别
- python - 授权标头错误:没有名为“certifi”的模块,python 请求 API
- response - 查询的不同响应
- android - 如何删除代码中的 ConstraintLayout 链样式?
- javascript - jQuery 引用 if 语句的元素
- git - 如何仅将一个提交合并到 master 而不是分支的所有提交?