在 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