【发布时间】:2010-09-17 21:46:53
【问题描述】:
我需要从很多行中获取摘要数据。汇总字段是对不同字段的每个值有多少条目的计数。例如,一个包含人的年龄、城市、工作等的表格,汇总数据将包括每个工作的“countManager”、“countCodeMonkey”等字段,然后是城市的“countChicago”、“countNewYork”等字段。
我知道获取一切的简单方法是:
select count(*) from table
group by age, city, job
但这是垂直计数 - 我需要的每个值都有不同的行。我需要字段而不是带有计数的行,因为我还有其他字段可以分组,例如状态。所以我希望我的结果看起来像这样:
| State | countManager | countMonkey |
| IL | 3 | 25 |
| NY | 5 | 40 |
我正在寻找两种方法来做到这一点。我们已经实现了一个,执行需要 20 分钟。我想知道其他方式是否会更快。
目前的方式是这样的:
create view managers as
select state, count(*) as theCount from table
where job = 'Manager'
group by state;
create view monkeys as
select state, count(*) as theCount from table
where job = 'Monkey'
group by state;
select managers.theCount as managers, monkeys.theCount as monkeys
from managers left join monkeys
on managers.state = monkeys.state;
在实际情况下,大约有 20 个视图,因此还有 20 个连接。
我正在考虑使用以下水平计数方法:
select state,
sum(case when job='Manager' then 1 else 0 end) as managers,
sum(case when job='Monkey' then 1 else 0 end) as monkeys
from table
group by state;
这消除了连接。但我对“sum case”语句的表现一无所知。这会更快,差不多还是慢得多?引擎是否必须多次遍历行,每个这样的计数字段一次?或者它是否足够聪明,可以一次计算所有字段,检查每个值并增加适当的总和?
我可能会花一天的时间编写一个脚本来生成大量垃圾数据来测试这一点,但我仍然想知道 db 引擎的行为,这是我在网上其他地方找不到的。
【问题讨论】:
-
这可能取决于所涉及的数据库引擎。你想到了哪一个?
-
如果您有 Microsoft SQL Server,他们有一个查询计划,可以直观地向您展示数据库引擎如何解析/执行您的查询
-
我相信我们正在使用 Postgres。
-
第二个对我来说似乎效率更高。它只需要一次通过数据。不过,我对 postgres 的了解还不够,无法肯定地说。
标签: sql database postgresql query-optimization