【问题标题】:Most optimized way to get column totals in SQL Server 2005+在 SQL Server 2005+ 中获取列总计的最优化方法
【发布时间】:2010-10-13 14:57:52
【问题描述】:

我正在为一个应用程序创建一些报告,供各个州使用。数据库有可能非常大。我想知道哪种方式是获取列总计的最佳方式。

目前我的 SQL 类似于以下内容:

SELECT count(case when prg.prefix_id = 1 then iss.id end) +
       count(case when prg.prefix_id = 2 then iss.id end) as total,
       count(case when prg.prefix_id = 1 then iss.id end) as c1,
       count(case when prg.prefix_id = 2 then iss.id end) as c2
FROM dbo.TableName
WHERE ...

如您所见,列在其中两次。在一种情况下,我将它们相加并显示总数,在另一种情况下,我只显示报告所需的各个值。

这是一个非常小的 SQL 示例,有 20 多列,并且有时会将其中 4 列或更多列相加。

我正在考虑声明一些@Parameters 并将每个列设置为等于一个@Parameter,然后我可以添加我需要显示列总数的@Parameters,即:SET @Total = @c1 + @c2

但是,SQL Server 引擎是否会像这样多次关心列在其中?有更好的方法吗?

【问题讨论】:

    标签: sql sql-server-2005 sql-server-2008 query-optimization sql-optimization


    【解决方案1】:

    不这样做的任何原因

    select prg.prefix_id, count(1) from tablename where... group by prg.prefix_id     
    

    它会给你一个prefix_id的结果集和每个prefix_ID的行数......可能比一系列count(case)语句更优惠,我认为它应该更快,但我可以' t 确定。

    我会在自己使用@vars 之前使用子查询。像这样的:

       select c1,c2,c1+c1 as total from 
       (SELECT 
       count(case when prg.prefix_id = 1 then iss.id end) as c1, 
       count(case when prg.prefix_id = 2 then iss.id end) as c2 
       FROM dbo.TableName 
       WHERE ... ) a
    

    【讨论】:

    • 我不能使用第一个选项,因为 COUNT 中的 CASE 语句比您实际看到的要复杂一些。我想我会尝试改变你和其他发布的建议。使用 CTE 而不是内联视图。不确定这是否会有所作为。
    • 不管 case 语句有多复杂,我都希望将结果作为 ID 列,计数。更复杂的 case 语句只会有更多的 ID 列。将此 count 语句转换为子查询,然后根据需要从子查询中进行选择,可能包括将子查询连接到自身以以您想要的方式呈现结果。可能只是我个人的偏好...select ID,column(s) 优先于 select column_where_id=1, column_where_id=2,column_where_id=etc...
    【解决方案2】:

    在使用 T-SQL 过程逻辑之前,尽可能使用直接 SQL。经验法则,如果您可以在 SQL 中执行,请在 SQL 中执行。如果你想用直接的 SQL 模拟静态值,试试这样的内联视图:

    SELECT iv1.c1 + iv1.c2 as total,
           iv1.c1,
           iv1.c2
        FROM
        (
        SELECT count(case when prg.prefix_id = 1 then iss.id end) as c1,
               count(case when prg.prefix_id = 2 then iss.id end) as c2
        FROM dbo.TableName
        WHERE ...
        ) AS iv1
    

    通过这种方式,您可以在逻辑上获得一次计数,并可以根据这些计数计算值。但是我认为 SQL Server 足够聪明,不必扫描计数 n 次,所以我不知道您的计划会与我发送的 SQL 和您拥有的 SQL 不同。

    【讨论】:

    • SQL 总是会超出执行过程逻辑。
    • 除非您使用的是 1 行数据集 ;) 我想知道我是否应该在此评论上添加 [badjoke] [/badjoke] 标签
    猜你喜欢
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    相关资源
    最近更新 更多