【发布时间】:2016-08-12 18:36:45
【问题描述】:
我有这个 QA 逻辑,可以在 RoomID 中的每个 AuditID 中查找错误,以查看它们的 AuditType 是否从未标记为 Complete 或者它们是否具有两个完整状态。最后,它只选择有错误的RoomIDs 中最大的AuditDate,以避免显示相同RoomID 的多个实例,因为每个房间有很多审计。
问题在于 AUDIT 表非常大,需要很长时间才能运行。我想知道是否有任何方法可以更快地达到相同的结果。
提前谢谢你!
IF object_ID('tempdb..#AUDIT') is not null drop table #AUDIT
IF object_ID('tempdb..#ROOMS') is not null drop table #ROOMS
IF object_ID('tempdb..#COMPLETE') is not null drop table #COMPLETE
IF object_ID('tempdb..#FINALE') is not null drop table #FINALE
SELECT distinct
oc.HotelID, o.RoomID
INTO #ROOMS
FROM dbo.[rooms] o
LEFT OUTER JOIN dbo.[hotels] oc on o.HotelID = oc.HotelID
WHERE
o.[status] = '2'
AND o.orderType = '2'
SELECT
t.AuditID, t.RoomID, t.AuditDate, t.AuditType
INTO
#AUDIT
FROM
[dbo].[AUDIT] t
WHERE
t.RoomID IN (SELECT RoomID FROM #ROOMS)
SELECT
t1.RoomID, t3.AuditType, t3.AuditDate, t3.AuditID, t1.CompleteStatus
INTO
#COMPLETE
FROM
(SELECT
RoomID,
SUM(CASE WHEN AuditType = 'Complete' THEN 1 ELSE 0 END) AS CompleteStatus
FROM
#AUDIT
GROUP BY
RoomID) t1
INNER JOIN
#AUDIT t3 ON t1.RoomID = t3.RoomID
WHERE
t1.CompleteStatus = 0
OR t1.CompleteStatus > 1
SELECT
o.HotelID, o.RoomID,
a.AuditID, a.RoomID, a.AuditDate, a.AuditType, a.CompleteStatus,
c.ClientNum
INTO
#FINALE
FROM
#ROOMS O
LEFT OUTER JOIN
#COMPLETE a on o.RoomID = a.RoomID
LEFT OUTER JOIN
[dbo].[clients] c on o.clientNum = c.clientNum
SELECT
t.*,
Complete_Error_Status = CASE WHEN t.CompleteStatus = 0
THEN 'Not Complete'
WHEN t.CompleteStatus > 1
THEN 'Complete More Than Once'
END
FROM
#FINALE t
INNER JOIN
(SELECT
RoomID, MAX(AuditDate) AS MaxDate
FROM
#FINALE
GROUP BY
RoomID) tm ON t.RoomID = tm.RoomID AND t.AuditDate = tm.MaxDate
【问题讨论】:
-
当您可以简单地通过
WHERE AuditType = 'Complete'过滤数据集时,为什么要使用SUM(CASE WHEN AuditType = 'Complete' THEN 1 ELSE 0 END)? -
@Nicarus 我的思考过程是我正在查看所有在 roomID 中 AuditType = 'complete' 的实例。无论如何,如果您知道更好的方法..我在这里学习..
-
考虑索引您的临时表。 WHERE EXISTS 通常(但不总是)比 IN 快。 OR 很慢,尽可能用 UNION ALL 替换。
-
@H.Ben - 我的意思是你没有限制数据集,但你只是对有限的数据集求和。这是不必要的。
-
您使用的是 2012 年或更高版本的 sql-server 哪个版本?通读此查询,您可能可以转储/不使用大量临时表,从而更有效地限制连接结果并使用 MAX() OVER 窗口函数,它应该执行得更好,但最终索引的内容和不索引的内容以及其他几件事也很关键
标签: sql sql-server optimization query-optimization