【问题标题】:Slow SQL query based on from date基于起始日期的慢速 SQL 查询
【发布时间】:2017-10-20 09:03:45
【问题描述】:

我收到了一个要运行的查询(如下),在我创建的应用程序中,起始日期可以在运行时更改。因此,如果我运行“2010 年 1 月 1 日”的开始日期,我会检索更多数据(返回 216620 行),然后如果我使用 3 天前的日期“2017 年 10 月 17 日”(返回 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]

【问题讨论】:

  • 您有我们可以看到的用于识别瓶颈的查询计划
  • 我编辑了我的帖子以提出查询计划。希望能给你足够的信息。
  • 不确定您的事务表有多大,但是在它的两侧都有聚集索引扫描的嵌套循环可以从事务表上的至少一个(如果不是两个)NCI 中受益。跨度>
  • 96% 的执行时间用于索引扫描。也许更快的日期更容易访问。碎片化情况如何?磁盘上的 io 速度变慢了吗?
  • Transaction 表共有 492443 行。没有任何 IO 问题或碎片问题。我正在考虑使用索引视图,但从我读到的内容来看,这在写入少、读取多的情况下会更好。但这张表每天大约有 250 次写入。

标签: sql sql-server database optimization


【解决方案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

【讨论】:

    【解决方案2】:

    好吧,我找到了一种使查询更快的方法,但我不确定它为什么会起作用。 我从事务表(492k+ 行)中选择,修改有问题的查询,最后从该查询中查询。我无法解释为什么会这样,但它使查询变得很快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-01
      • 2013-06-11
      • 2021-02-17
      • 2023-03-15
      • 2021-11-14
      • 1970-01-01
      • 2012-02-04
      相关资源
      最近更新 更多