我需要从许多行中获取摘要数据。摘要字段是不同字段的每个值的条目数。例如,一个包含人的年龄,城市,工作等的表格,摘要数据将包括每个作业的“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;
这消除了连接。但我不清楚“总和案例”陈述的表现。这会更快,大致相同,还是慢得多?引擎是否必须多次遍历行,对于每个这样计算的字段一次?或者它是否足够聪明,可以计算一次运行中的所有字段,检查每个值并递增适当的总和?
我可能会花一天时间编写一个脚本来生成大量垃圾数据来测试它,但我仍然想知道db引擎的行为,我在网上其他地方找不到。
答案 0 :(得分:3)
完全取决于引擎以及您希望如何查看数据,但您的第二个选项应该更快地完成。
即使你的第一个查询20分钟也是荒谬的,除非你有数十亿行。在这种情况下,您应该每月/每周查看归档数据,并在表格中预编译汇总数据,您可以在其中切片和切块以适应。
答案 1 :(得分:1)
如果您的交易与其他交易不存在并发,“总和案例”是一个不错的选择。聚合函数AVG
,SUM
,GROUP BY
会降低性能。与两件事保持联系:“分而治之”和“数字数据比文本数据更快”。
创建一个数据仓库(单个表,一个数据库)以避免并发并加速处理。
CPU是非常棒的计算器:通过数字数据("NY"
,{{1}转换您的分类数据("LA"
,"Man"
,"Woman"
,1
) }},2
,61
)并改善您的挖掘。
清理您对数据库供应商或平台选择的看法,但关系代数。