jdi*_*n04 7 postgresql performance postgresql-performance
我有一个场景,我需要运行工资报告。该报告计算特定日期范围内按员工分组的工资金额。
例如,当运行 2016-11-01 到 2016-11-30 的报告时,我会看到以下结果:
Staff Id Total
------------------
1 123.00
2 439.22
Run Code Online (Sandbox Code Playgroud)
我对上述报告使用以下查询:
select
user_id as staff_id,
sum(amount) as total
from transaction
where
business_id = <business_id> and
type = 'staff' and
kind = 'commission' and
created_at between <start_date> and <end_date>
group by
user_id;
Run Code Online (Sandbox Code Playgroud)
我正在尝试根据以下要求确定优化此查询性能的最佳方法:
business_id
、start_date
和end_date
看来视图和函数都可以完成这项工作,但我并不能 100% 确定哪种方法是考虑到需求的最佳方法。
旁注:如果能够根据上面提到的参数来缓存数据就太好了,但是数据库方面似乎没有很好的解决方案。如我错了请纠正我!
附加信息:
business_id
、type
、kind
和列上有索引。这些都是单列、btree 索引。user_id
created_at
transaction
视图无法帮助您根据未知参数(business_id
、start_date
和end_date
)生成聚合。它只不过是一个给定的查询,永久存储在数据库中以供以后重用。(嗯,实现比较复杂,但这并不影响它们的使用。)
考虑到您的查询,您可以获得的最远视图是
CREATE VIEW staff_commission AS
SELECT
user_id AS staff_id,
business_id,
amount,
start_date,
end_date
FROM transaction
WHERE
type = 'staff' AND
kind = 'commission';
Run Code Online (Sandbox Code Playgroud)
事先已知的所有内容都在那里,加上生成所需输出所需的列。
为了获得后者,您必须在任何情况下创建一个函数(可选地,从视图工作)。当您有多个以相同方式过滤日期的查询时,基于视图进行构建是有意义的。
所有这些的性能都将是相同的。索引是否有意义很大程度上取决于实际数据。(不过,我很确定您不需要所有这些。)如果不了解这些,就很难猜测需要哪些改进。尝试一下你所拥有的,检查输出EXPLAIN ANALYZE
并看看是否缺少某些东西。
最后关于缓存:PostgreSQL 在这方面非常聪明。深入细节将占据一本书的一两章,但我不会担心这一点,直到我看到太多的磁盘读取(可以从EXPLAIN (ANALYZE, BUFFERS)
)。
归档时间: |
|
查看次数: |
9946 次 |
最近记录: |