繁体   English   中英

SQL Server / T-SQL:查询优化帮助

[英]SQL Server / T-SQL : query optimization assistance

我有一个看起来错误到每一个这样的QA逻辑AuditID一个内RoomID ,看看他们AuditType从未标注齐全或者如果他们有两个完整的状态。 最后,由于每个房间有很多审核,它只选择有错误的RoomID的最大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

只是一个想法。 简化代码和解决方案。 您没有有效地过滤较小的数据集,因此您将继续查询占用大量资源的整个表,而您的临时表已成为这些列的完整副本,而没有索引(PK,FK,++ ??)原始表可以利用。 这绝不是一个完美的解决方案,而是一个有关如何合并逻辑并减少总体数据集的想法。 尝试一下,看看它是否对您更好。

请注意,这将返回尚未完成审核或多次完成的所有房间的最后审核记录。

;WITH cte AS (
    SELECT
       o.RoomId
       ,o.clientNum
       ,a.AuditId
       ,a.AuditDate
       ,a.AuditType
       ,NumOfAuditsComplete = SUM(CASE WHEN a.AuditType = 'Complete' THEN 1 ELSE 0 END) OVER (PARTITION BY o.RoomId)
       ,RowNum = ROW_NUMBER() OVER (PARTITION BY o.RoomId ORDER BY a.AuditDate DESC)
    FROm
       dbo.Rooms o
       LEFT JOIN dbo.Audit a
       ON o.RoomId = a.RoomId
WHERE
   o.[Status] = 2
   AND o.OrderType = 2
)

SELECT
    oc.HotelId
    ,cte.RoomId
    ,cte.AuditId
    ,cte.AuditDate
    ,cte.AuditType
    ,cte.NumOfAuditsComplete
    ,cte.clientNum
    ,Complete_Error_Status = CASE WHEN cte.NumOfAuditsComplete > 1 THEN 'Complete More Than Once' ELSE 'Not Complete' END
FROM
    cte
    LEFT JOIN dbo.Hotels oc
    ON cte.HotelId = oc.HotelId
    LEFT JOIN dbo.clients c
    ON cte.clientNum = c.clientNum
WHERE
    cte.RowNum = 1
    AND cte.NumOfAuditsComplete != 1

另请注意,我更改了您的

WHERE 
    o.[status] = '2' 
    AND o.orderType = '2'

WHERE 
    o.[status] = 2 
    AND o.orderType = 2

为数字,不带单引号。 如果数据类型的确是varchar,则将它们添加回去,但是当您将数字列查询为varchar时,它将进行数据转换,并且可能不会利用在表上建立的索引。

您可以改进的部分就是这一部分。 请参阅内联注释。

SELECT 
    t1.RoomID, t3.AuditType, t3.AuditDate, t3.AuditID, t1.CompleteStatus
INTO 
    #COMPLETE
FROM
    (SELECT 
         RoomID,
         COUNT(1) AS CompleteStatus
         -- Use the above along with the WHERE clause below
         -- so that you are aggregating fewer records and
         -- avoiding a CASE statement. Remove this next line.
         --SUM(CASE WHEN AuditType = 'Complete' THEN 1 ELSE 0 END) AS CompleteStatus
     FROM 
         #AUDIT
     WHERE
         AuditType = 'Complete'
     GROUP BY 
         RoomID) t1
INNER JOIN
    #AUDIT t3 ON t1.RoomID = t3.RoomID
WHERE
    t1.CompleteStatus = 0
    OR t1.CompleteStatus > 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM