基于日期的慢SQL查询

时间:2017-10-19 14:28:29

标签: sql sql-server database optimization

我有一个查询要运行(下面),在应用程序中我可以在运行时更改创建起始日期。因此,如果我的开始日期为' 1/1/2010',我会检索更多数据(返回216620行),如果我在3天前使用了日期' 10/17/2017 && #39; (返回1006行),但由于某种原因该查询需要很长时间,并且在我的应用程序中它会超时。

此查询是否应以某种方式进行优化,或者这可能是服务器/硬件问题?我发现这个奇怪的过去3天的查询比跨越多年的数据查询要花费的时间长得多,不幸的是在我的WinForms应用程序中超时了

SELECT AC.account_and_parents As Account, 
    TR.IBLoad as [Load ID], 
    LD.load_inboundBOL as [Customer Details],
    TR.ItemNumber as ITEMNUM, 
    IT.[Description] As[Description], 
    TR.ToPalletID As[Pallet ID],
    Format(TR.Receivedate, 'MM/dd/yyyy') as Receive_Date, 
    TR.QTY as NETWEIGHT, 
    TR.WeightGross as [Gross Weight], 
    TR.ContainerType, 
    TR.InvenType,
    TR.Route,
    tr.ToWarehouse  as Warehouse,
    tr.category as Category, 
    tr.FGatIntake as [FG at Intake],
    CASE 
    When TR.FGatIntake = 1
    THEN
        (SELECT TOP 1 tr.ItemNumber FROM [databaseName].[dbo].[Transaction] TR1 WHERE TR1.ToPalletID = TR.ToPalletID and TransCode = 'FRCPT')
    END As[Finished Good]
    FROM [databaseName].[dbo].[Transaction] TR
    INNER JOIN [databaseName].[dbo].[Item] IT 
    on tr.ItemNumber = IT.ItemNumber
    INNER JOIN som5.dbo.Loads LD 
    on TR.IBLoad = LD.OID 
    INNER JOIN [SOM5].[dbo].[Accounts] AC
    on ld.load_Account = AC.OID

             --  PROBLEM IS HERE. Lots or records (January start) are fast,
             --    but few records (October start) are *very* slow. 
    WHERE (TransDateTime Between '10/16/2017' and '10/19/2017')
    and Transcode = 'BRCPT'
    and ToPalletID not in (Select FromPalletID FROM [SOM5].[dbo].[Transaction] where TransCode = 'UNBRCPT') 
        ORDER BY Receive_Date,[Load ID],[Pallet ID]

enter image description here

2 个答案:

答案 0 :(得分:1)

我最好的猜测是原始查询没有使用Where子句来尽快过滤行。

我会尝试重写查询,将主表的where子句放在子查询中。子查询应该具有优先级,返回一小部分数据;然后这些较少的行将连接到其他表并通过CASE语句。至于为什么可能更大的数据集执行如此迅速...我不确定,但我知道SQL Server缓存先前查询的结果。

SELECT AC.account_and_parents As Account, 
       TR.[Load ID], 
       LD.load_inboundBOL as [Customer Details],
       TR.ITEMNUM, 
       IT.[Description] As[Description], 
       TR.[Pallet ID],
       Format(TR.Receivedate, 'MM/dd/yyyy') as Receive_Date, 
       TR.NETWEIGHT, 
       TR.[Gross Weight], 
       TR.ContainerType, 
       TR.InvenType,
       TR.Route,
       tr.Warehouse,
       tr.category as Category, 
       tr.[FG at Intake],
       CASE 
       When TR.[FG at Intake] = 1
       THEN (SELECT TOP 1 tr.ItemNumber FROM [databaseName].[dbo].[Transaction] TR1 WHERE TR1.ToPalletID = TR.[Pallet ID] and TransCode = 'FRCPT')
    END As[Finished Good]
  FROM (
          SELECT IBLoad as [Load ID],
                 ItemNumber as ITEMNUM, 
                 ToPalletID As[Pallet ID],
                 Format(Receivedate, 'MM/dd/yyyy') as Receive_Date, 
                 QTY as NETWEIGHT, 
                 WeightGross as [Gross Weight], 
                 ContainerType, 
                 InvenType,
                 Route,
                 ToWarehouse  as Warehouse,
                 category as Category, 
                 FGatIntake as [FG at Intake]
            FROM [databaseName].[dbo].[Transaction]
           WHERE TransDateTime >= '2017-10-16'
             AND TransDateTime <= '2017-10-19'
       ) AS TR INNER JOIN [databaseName].[dbo].[Item] IT on tr.ITEMNUM = IT.ItemNumber
               INNER JOIN som5.dbo.Loads LD on TR.[Load ID] = LD.OID 
               INNER JOIN [SOM5].[dbo].[Accounts] AC on ld.load_Account = AC.OID

答案 1 :(得分:0)

我找到了一种方法来提高查询速度,但我不确定为什么会这样做。  我从Transaction表中选择(492k +​​行),修改了有问题的查询,最后从中查询。我无法解释为什么这样有效,但它使查询变得快速。