2017-10-19 90 views
-1

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

该查询是否应该以某种方式进行优化,或者这可能是服务器/硬件问题?我只是觉得这个奇怪的查询在过去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

+1

你有一个查询计划,我们可以看到识别瓶颈 – MarkD

+1

我编辑我的帖子,把查询计划。希望给你足够的信息。 – Maverick

+1

不知道事务表有多大,但是在其两侧都有聚簇索引扫描的嵌套循环可以从事务处理表上至少有一个(如果不是两个)NCI受益。 –

回答

0

嗯,我找到了一个以更快的速度查询,尽管我不确定它为什么会起作用。 我从事务表(492k +​​行)中选择,修改了问题查询,最后从中查询。我无法解释为什么这会起作用,但它使查询变得很快。

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