SQL Server 2008 R2提高了查询性能

时间:2015-05-20 07:04:57

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

我有一个问题:

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一起工作。我想,我创建了所有需要的索引。 我有另外两个这样的查询,并尝试将其结果插入到#TempTable中。这对我来说很慢。 你能帮我解决这个问题吗?

加了: 我为第一个查询创建了一些改进。现在需要7秒钟。但我还有另外两个问题:

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. TransactionQuater,FCC
  3. TransactionQuater包含表格中的所有其他字段
  4. 我认为索引有什么问题

1 个答案:

答案 0 :(得分:0)

该计划显示基数估计失败。

enter image description here

绿色运算符估计执行1次,但执行次数为100,000次。

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

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