在 SQL Server 2005+ 中获取列总计的最优化方法

Posted

技术标签:

【中文标题】在 SQL Server 2005+ 中获取列总计的最优化方法【英文标题】:Most optimized way to get column totals in 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 引擎是否会像这样多次关心列在其中?有更好的方法吗?

【问题讨论】:

【参考方案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] 标签

以上是关于在 SQL Server 2005+ 中获取列总计的最优化方法的主要内容,如果未能解决你的问题,请参考以下文章

当 SQL Server 总计出现在第一行而不是表末尾时出错

从 Ms Access Mdb 文件获取数据到 sql server 2005 的最佳方法

更新表以按分组列显示总计 SQL Server 2008 R2

如何在 SQL Server 2005 中将随机数作为列返回?

SQL Server 2008 累计运行总计

使用 SqlDataAdapter 时获取 SQL Server DATEDIFF 列作为 TimeSpan