使用GROUP BY ALL的缺点?

时间:2013-12-27 09:54:20

标签: sql sql-server sql-server-2008 group-by

我总是在ALL子句的上下文中查看GROUP BY关键字是非常有用和有意义的。使用时我没有遇到任何性能问题。

MSDN documentation表示它将是EOL(自2005年起),并建议不要在生产代码中使用它,但在最新版本的SQL Server之前仍然支持它。

不使用它会对性能产生影响或其他实际原因吗?

1 个答案:

答案 0 :(得分:4)

你可以替换

SELECT AggregateFunction(AggColumn) 
FROM ... 
WHERE Predicate GROUP BY ALL GrpColumn

SELECT AggregateFunction(CASE WHEN Predicate THEN AggColumn END) 
FROM ... 
GROUP BY GrpColumn

示例:

SELECT  p.ProductID, MAX(p.UnitPrice) AS MAX_UnitPrice
FROM (
    SELECT 1, 100 UNION ALL
    SELECT 1, 10.5 UNION ALL
    SELECT 1, 10 UNION ALL
    SELECT 2, 55 UNION ALL
    SELECT 2, 99
) p(ProductID, UnitPrice)
WHERE p.ProductID = 1
GROUP BY ALL p.ProductID;

SELECT  p.ProductID, 
        MAX(CASE WHEN p.ProductID = 1 THEN p.UnitPrice END) AS MAX_UnitPrice
FROM (
    SELECT 1, 100 UNION ALL
    SELECT 1, 10.5 UNION ALL
    SELECT 1, 10 UNION ALL
    SELECT 2, 55 UNION ALL
    SELECT 2, 99
) p(ProductID, UnitPrice)
GROUP BY ALL p.ProductID;

修改1:

SET NOCOUNT ON;
SET STATISTICS IO ON;

PRINT 'Test #1: GROUP BY ALL'
SELECT  p.ProductModelID, 
        MAX(p.ListPrice) AS MAX_ListPrice
FROM    Production.Product p
WHERE   p.Color = 'Red'
GROUP BY ALL p.ProductModelID

PRINT 'Test #2: GROUP BY + MAX(CASE WHEN)'
SELECT  p.ProductModelID, 
        MAX(CASE WHEN p.Color = 'Red' THEN p.ListPrice END) AS MAX_ListPrice
FROM    Production.Product p
GROUP BY p.ProductModelID

STATISTICS IO输出:

Test #1: GROUP BY ALL
Table 'Product'. Scan count 2, logical reads 30

Test #2: GROUP BY + MAX(CASE WHEN)
Table 'Product'. Scan count 1, logical reads 15

实际执行计划: enter image description here

从性能的角度来看,从这个测试(我使用Adventure Works 2008 R2)我们可以看到GROUP BY ALL强制SQL Server两次读取相同的数据:

  • 执行计划有两个Index Scan操作符,
  • STATISTICS IO ON的输出还显示2次扫描和数量。 GROUP BY ALL的逻辑读取(在我的测试中)大于num。非GROUP BY ALL解决方案的逻辑读取。此外,创建索引不会改变这种情况:2名运营商扫描和/或寻找GROUP BY ALL vs。 1运营商扫描或寻找GROUP BY + MAX(CASE WHEN)