我有一个问题:
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个索引:
我认为索引有什么问题
答案 0 :(得分:0)
该计划显示基数估计失败。
绿色运算符估计执行1次,但执行次数为100,000次。
我现在没时间找出为什么存在基数估算错误。这将是首选方法。也许更好的统计或索引可以帮助。第一个标记运算符之前的连接被错误估计。调查一下。在已连接的列上创建更好的索引。
快速解决方案是将FORCESCAN
打到这些表引用上。这可能会导致SQL Server选择哈希联接并为您提供稳定的计划。 FORCESCAN
非常非侵入性。不幸的是,加入提示强制连接顺序,这是SQL Server部分无法忍受的愚蠢行为。它使连接提示在大多数情况下都无法使用,即使它们是合适的。