【问题标题】:SQL Server 2008 R2 improving query performanceSQL Server 2008 R2 提高查询性能
【发布时间】:2015-08-01 06:44:34
【问题描述】:

我有一个问题:

SELECT  
      2015, 
      d.TransactionQuater, 
      atc1bf.atc1_id, 
      atc2bf.atc2_id, 
      atc3bf.atc3_id, 
      atc4bf.atc4_id, 
      bf.BU_id, 
      mbf.Manufacturer_id, 
      pbf.Product_id, 
      SUM(d.Units) AS Units, 
      SUM(d.ExMnf_LC*Units) AS ExMnf_LC
FROM dbo.FF_Data_2013_short AS d 
INNER JOIN ATC1ByFCC atc1bf ON d.FCC = atc1bf.FCC 
INNER JOIN ATC2ByFCC atc2bf ON d.FCC = atc2bf.FCC 
INNER JOIN ATC3ByFCC atc3bf ON d.FCC = atc3bf.FCC 
INNER JOIN ATC4ByFCC atc4bf ON d.FCC = atc4bf.FCC
INNER JOIN ManufacturerByFCC mbf ON d.FCC = mbf.FCC 
INNER JOIN ProductByFCC pbf ON d.FCC = pbf.FCC
INNER JOIN BUByFCC bf ON d.FCC = bf.FCC 
WHERE d.TransactionQuater between  1 AND 1
GROUP BY 
       TransactionQuater,  
       atc1bf.atc1_id,
       atc2bf.atc2_id,
       atc3bf.atc3_id,
       atc4bf.atc4_id,
       bf.BU_id, 
       mbf.Manufacturer_id, 
       pbf.Product_id

此查询执行大约 13 分钟并获取大约 16000 条记录。如果我评论 group by 和 sum,查询执行得更快并获取大约 4000000 条记录。我希望 SQL Server 可以更好地使用 group by。我想,我创建了所有需要的索引。 我还有 2 个类似的查询,并尝试将其结果插入 #TempTable。这对我来说太慢了。 你能帮我这个查询的性能吗?

添加: 我为第一个查询做了一些改进。现在需要 7 秒。但我还有 2 个疑问:

SELECT  
      2014, 
      d.TransactionQuater, 
      atc1bf.atc1_id, 
      atc2bf.atc2_id, 
      atc3bf.atc3_id, 
      atc4bf.atc4_id, 
      bf.BU_id, 
      mbf.Manufacturer_id, 
      pbf.Product_id, 
      SUM(d.Units) AS Units, 
      SUM(d.ExMnf_LC*Units) AS ExMnf_LC
FROM dbo.FF_Data_2014_short AS d 
INNER JOIN ATC1ByFCC atc1bf ON d.FCC = atc1bf.FCC 
INNER JOIN ATC2ByFCC atc2bf ON d.FCC = atc2bf.FCC 
INNER JOIN ATC3ByFCC atc3bf ON d.FCC = atc3bf.FCC 
INNER JOIN ATC4ByFCC atc4bf ON d.FCC = atc4bf.FCC
INNER JOIN ManufacturerByFCC mbf ON d.FCC = mbf.FCC 
INNER JOIN ProductByFCC pbf ON d.FCC = pbf.FCC
INNER JOIN BUByFCC bf ON d.FCC = bf.FCC
GROUP BY 
       TransactionQuater,  
       atc1bf.atc1_id,
       atc2bf.atc2_id,
       atc3bf.atc3_id,
       atc4bf.atc4_id,
       bf.BU_id, 
       mbf.Manufacturer_id, 
       pbf.Product_id

无条件,耗时约8分钟,获取约65000条记录 和

SELECT  
      2013, 
      d.TransactionQuater, 
      atc1bf.atc1_id, 
      atc2bf.atc2_id, 
      atc3bf.atc3_id, 
      atc4bf.atc4_id, 
      bf.BU_id, 
      mbf.Manufacturer_id, 
      pbf.Product_id, 
      SUM(d.Units) AS Units, 
      SUM(d.ExMnf_LC*Units) AS ExMnf_LC
FROM dbo.FF_Data_2013_short AS d 
INNER JOIN ATC1ByFCC atc1bf ON d.FCC = atc1bf.FCC 
INNER JOIN ATC2ByFCC atc2bf ON d.FCC = atc2bf.FCC 
INNER JOIN ATC3ByFCC atc3bf ON d.FCC = atc3bf.FCC 
INNER JOIN ATC4ByFCC atc4bf ON d.FCC = atc4bf.FCC
INNER JOIN ManufacturerByFCC mbf ON d.FCC = mbf.FCC 
INNER JOIN ProductByFCC pbf ON d.FCC = pbf.FCC
INNER JOIN BUByFCC bf ON d.FCC = bf.FCC 
WHERE d.TransactionQuater between  2 AND 4
GROUP BY 
       TransactionQuater,  
       atc1bf.atc1_id,
       atc2bf.atc2_id,
       atc3bf.atc3_id,
       atc4bf.atc4_id,
       bf.BU_id, 
       mbf.Manufacturer_id, 
       pbf.Product_id

大约需要 4 分钟,得到大约 45000 条记录

我继续我的实验:以下查询:

SELECT  
      2011, 
      d.TransactionQuater, 
      atc1bf.atc1_id, 
      atc2bf.atc2_id, 
      atc3bf.atc3_id, 
      atc4bf.atc4_id, 
      bf.BU_id, 
      mbf.Manufacturer_id, 
      pbf.Product_id, 
      SUM(d.Units) AS Units, 
      SUM(d.ExMnf_LC*Units) AS ExMnf_LC
FROM dbo.FF_Data_2011_short AS d with(ForceScan)
INNER JOIN ATC1ByFCC atc1bf ON d.FCC = atc1bf.FCC 
INNER JOIN ATC2ByFCC atc2bf ON d.FCC = atc2bf.FCC 
INNER JOIN ATC3ByFCC atc3bf ON d.FCC = atc3bf.FCC 
INNER JOIN ATC4ByFCC atc4bf ON d.FCC = atc4bf.FCC
INNER JOIN ManufacturerByFCC mbf ON d.FCC = mbf.FCC 
INNER JOIN ProductByFCC pbf ON d.FCC = pbf.FCC
INNER JOIN BUByFCC bf ON d.FCC = bf.FCC 
WHERE d.TransactionQuater between  2 AND 4
GROUP BY 
       TransactionQuater,  
       atc1bf.atc1_id,
       atc2bf.atc2_id,
       atc3bf.atc3_id,
       atc4bf.atc4_id,
       bf.BU_id, 
       mbf.Manufacturer_id, 
       pbf.Product_id

使用 FORCESCAN 执行 2 分钟,不使用 FORCESCAN 执行 4 分钟。计划在这里:https://onedrive.live.com/redir?resid=B5ED432740B0672D!175&authkey=!AEM8f7O8qazZVK0&ithint=folder%2c 数据表只有 3 个索引:

  1. FCC 包含表中的所有其他字段
  2. 交易季,FCC
  3. TransactionQuater 包含表中的所有其他字段

我猜索引有什么问题

【问题讨论】:

  • 在 SSMS 中,通过单击按钮或按ctrl+m 包含实际执行计划,然后运行查询。这将在名为execution plan 的结果部分中添加另一个浴缸。 If 将为您提供查看查询瓶颈所在位置所需的数据,甚至可能会建议您添加索引。
  • 我试图查看执行计划。它没有对我有用的信息
  • 计划是:onedrive.live.com/…
  • 它们看起来不错,你不能将第一个查询的相同解决方案应用于其他 2 个吗?
  • 我已经完成了。它减少了执行时间,但仍然很大(如问题)

标签: sql sql-server performance sql-server-2008


【解决方案1】:

计划显示基数估计失败。

绿色算子估计执行了 1 次,但执行了 100,000 次。

我现在没有时间找出为什么会出现基数估计错误。那将是首选方法。也许更好的统计数据或索引会有所帮助。第一个标记运算符之前的连接被错误估计。调查那个。在连接列上创建更好的索引。

一个快速的解决方案是将FORCESCAN 打到这些表引用上。这可能会导致 SQL Server 选择散列连接并为您提供稳定的计划。 FORCESCAN 非常无创。不幸的是,加入提示强制加入顺序,这在 SQL Server 部分是无法忍受的愚蠢行为。它使连接提示在大多数情况下都无法使用,即使它们是合适的。

【讨论】:

  • 不幸的是,我无法使用此提示,因为错误:“forcescan”不是可识别的表提示选项。如果它打算作为表值函数或 CHANGETABLE 函数的参数,请确保您的数据库兼容模式设置为 90。我不明白,是不是 bug?
  • 你是不是像这里的例子那样做? msdn.microsoft.com/en-us/library/ms187373.aspx您有最低要求的 SQL Server 版本吗?
  • 您需要新的解决方案还是可以应用 SP1?无论如何,这是个好主意。
  • 我尝试使用 FORCESCAN。处决次数减少。但查询执行速度较慢
  • 发布新计划。从计划中可以看出放缓的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多