【发布时间】:2015-09-02 17:25:50
【问题描述】:
我有一个查询,感觉它需要的时间比它应该的要多。这仅适用于给定参数集的第一次查询,因此缓存时没有问题。
我不确定会发生什么,但是,考虑到设置和设置,我希望有人可以阐明一些问题,并深入了解可以采取哪些措施来加快查询速度。有问题的表相当大,Postgres 估计其中大约有 155963000 (14 GB)。
查询
select ts, sum(amp) as total_amp, sum(230 * factor) as wh
from data_cbm_aggregation_15_min
where virtual_id in (1818) and ts between '2015-02-01 00:00:00' and '2015-03-31 23:59:59'
and deleted is null
group by ts
order by ts
当我开始研究这个查询时,它花了大约 15 秒,经过一些更改后,我将它缩短到了大约 10 秒,对于像这样的简单查询来说,这似乎仍然很长。以下是来自explain analyze 的结果:http://explain.depesz.com/s/97V1。注意GroupAggregate 返回相同数量的行的原因是这个例子只使用了一个virtual_id,但可以有更多。
表格和索引
正在查询的表,每 15 分钟插入一次值
CREATE TABLE data_cbm_aggregation_15_min (
virtual_id integer NOT NULL,
ts timestamp without time zone NOT NULL,
amp real,
recs smallint,
min_amp real,
max_amp real,
deleted boolean,
factor real DEFAULT 0.25,
min_amp_ts timestamp without time zone,
max_amp_ts timestamp without time zone
)
ALTER TABLE data_cbm_aggregation_15_min ALTER COLUMN virtual_id SET STATISTICS 1000;
ALTER TABLE data_cbm_aggregation_15_min ALTER COLUMN ts SET STATISTICS 1000;
查询中使用的索引
CREATE UNIQUE INDEX idx_data_cbm_aggregation_15_min_virtual_id_ts
ON data_cbm_aggregation_15_min USING btree (virtual_id, ts DESC);
ALTER TABLE data_cbm_aggregation_15_min
CLUSTER ON idx_data_cbm_aggregation_15_min_virtual_id_ts;
Postgres 设置
其他设置为默认设置。
default_statistics_target = 100
maintenance_work_mem = 2GB
effective_cache_size = 11GB
work_mem = 256MB
shared_buffers = 3840MB
random_page_cost = 1
我尝试过的
我一直在关注你在https://wiki.postgresql.org/wiki/Slow_Query_Questions 发帖之前要尝试的事情,更详细的结果如下:
- 摆弄 Postgres 设置,主要是在索引扫描后降低
random_page_cost,虽然它似乎并不太特别,但它比random_page_cost更高时尝试执行的位图堆扫描领先几英里。 - 向索引和
WHERE条件所基于的virtual_id和ts列添加更多统计信息。更改后,查询规划器的估计行数更接近实际行数。 -
the idx_data_cbm_aggregation_15_min_virtual_id_ts索引上的聚类似乎没有太大变化,我没有注意到。 - 手动运行
VACUUM并没有太大变化,我已经在运行 autovacuum 所以这不足为奇。 - 在索引上运行
REINDEX大大缩小了它(几乎 50%!),但速度并没有提高多少。
【问题讨论】:
-
数据是如何分布的?即,
virtual_id有多少不同的值,它们的行数是否大致相同?您通常是按整月查询,还是可以任意查询时间范围? -
截至目前,表中有 15256 个不同的
virtual_id值。与每个virtual_id关联的总行数各不相同,但它们都以相同的速率获取数据,因此变化取决于它们的创建时间。有问题的查询将具有任意时间范围。
标签: postgresql configuration query-optimization postgresql-9.2 postgresql-performance