无需昂贵连接的 MSSQL 查询优化
MSSQL Query Optimization Without Expensive Join
我们正在开发一个查询,以尝试查找 table 中最近的消息事件出错的所有消息。这些消息可以重新处理,并且有可能使它们处于良好状态,这就是为什么我们正在寻找最新的消息,甚至是错误的消息。我们的 SQL 并不强大,我们目前 运行 的查询比我们希望 运行 花费的时间长得多。除了添加索引或缩小 table 大小之外,还有什么可以帮助此查询 运行 更快吗?这可以在没有连接的情况下完成吗?
SELECT M.MessageID AS MessageID,
Source,
IntakeTimestamp,
MessageKey,
MessageSourceID,
CustomerID,
AgreementID,
LocationID,
EquipmentID,
OfficeID,
IncidentID,
M.HistoryID AS HistoryID,
Subject,
FromHeader,
ToHeader,
PackedHeaders
FROM [pipe].[Message] AS M
JOIN [pipe].[MessageState] AS MS ON MS.MessageID = M.MessageID
WHERE MessageStateID IN (
SELECT TOP 1 MessageStateID FROM [pipe].[MessageState] AS NMS
WHERE M.MessageID = NMS.MessageID
AND MS.EventStatusID = 6
ORDER BY MessageStateID DESC )
ORDER BY [MessageID] DESC
我能够使用下面的简单查询提取所有处于错误状态的消息,但这并没有只检查最近的消息状态
SELECT * FROM [pipe].[Message]
WHERE MessageID IN (
SELECT *
FROM [pipe].[MessageState]
WHERE EventStatusID = 6
)
您可以尝试类似下面的操作来查找每个 MessageID
的最新记录,假设您的 MessageStateID
排序适合您的数据。这是通过为具有相同 MessageID
值的每组行分配一个按 MessageStateID
值降序排列的行号来实现的。在这样做时,任何 rn
值为 1
的记录都是该 MessageID
:
的最新记录
WITH m AS
(
SELECT M.MessageID,
Source,
IntakeTimestamp,
MessageKey,
MessageSourceID,
CustomerID,
AgreementID,
LocationID,
EquipmentID,
OfficeID,
IncidentID,
M.HistoryID AS HistoryID,
Subject,
FromHeader,
ToHeader,
PackedHeaders,
MS.EventStatusID,
ROW_NUMBER() OVER (PARTITION BY M.MessageID ORDER BY M.MessageStateID DESC) AS rn
FROM [pipe].[Message] AS M
JOIN [pipe].[MessageState] AS MS
ON MS.MessageID = M.MessageID
)
SELECT m.*
FROM m
WHERE m.rn = 1
AND m.EventStatusID = 6
ORDER BY m.MessageID DESC
我还建议您为所有列正确设置别名,以便您知道它们来自哪个 table。
我们正在开发一个查询,以尝试查找 table 中最近的消息事件出错的所有消息。这些消息可以重新处理,并且有可能使它们处于良好状态,这就是为什么我们正在寻找最新的消息,甚至是错误的消息。我们的 SQL 并不强大,我们目前 运行 的查询比我们希望 运行 花费的时间长得多。除了添加索引或缩小 table 大小之外,还有什么可以帮助此查询 运行 更快吗?这可以在没有连接的情况下完成吗?
SELECT M.MessageID AS MessageID,
Source,
IntakeTimestamp,
MessageKey,
MessageSourceID,
CustomerID,
AgreementID,
LocationID,
EquipmentID,
OfficeID,
IncidentID,
M.HistoryID AS HistoryID,
Subject,
FromHeader,
ToHeader,
PackedHeaders
FROM [pipe].[Message] AS M
JOIN [pipe].[MessageState] AS MS ON MS.MessageID = M.MessageID
WHERE MessageStateID IN (
SELECT TOP 1 MessageStateID FROM [pipe].[MessageState] AS NMS
WHERE M.MessageID = NMS.MessageID
AND MS.EventStatusID = 6
ORDER BY MessageStateID DESC )
ORDER BY [MessageID] DESC
我能够使用下面的简单查询提取所有处于错误状态的消息,但这并没有只检查最近的消息状态
SELECT * FROM [pipe].[Message]
WHERE MessageID IN (
SELECT *
FROM [pipe].[MessageState]
WHERE EventStatusID = 6
)
您可以尝试类似下面的操作来查找每个 MessageID
的最新记录,假设您的 MessageStateID
排序适合您的数据。这是通过为具有相同 MessageID
值的每组行分配一个按 MessageStateID
值降序排列的行号来实现的。在这样做时,任何 rn
值为 1
的记录都是该 MessageID
:
WITH m AS
(
SELECT M.MessageID,
Source,
IntakeTimestamp,
MessageKey,
MessageSourceID,
CustomerID,
AgreementID,
LocationID,
EquipmentID,
OfficeID,
IncidentID,
M.HistoryID AS HistoryID,
Subject,
FromHeader,
ToHeader,
PackedHeaders,
MS.EventStatusID,
ROW_NUMBER() OVER (PARTITION BY M.MessageID ORDER BY M.MessageStateID DESC) AS rn
FROM [pipe].[Message] AS M
JOIN [pipe].[MessageState] AS MS
ON MS.MessageID = M.MessageID
)
SELECT m.*
FROM m
WHERE m.rn = 1
AND m.EventStatusID = 6
ORDER BY m.MessageID DESC
我还建议您为所有列正确设置别名,以便您知道它们来自哪个 table。