postgresql – 对大表的第一次查询调用非常慢
我有一个问题,感觉它需要花费更多的时间.这仅适用于给定参数集的第一个查询,因此在缓存时没有问题.
我不确定会发生什么,但是,考虑到设置和设置,我希望有人可以对几个问题有所了解,并提供一些有关如何加快查询速度的见解.该表格相当大,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较高时,它尝试做的位图堆扫描提前了几英里. 解决方法
一些小的改进
SELECT ts,sum(amp) AS total_amp,sum(factor) * 230 AS wh FROM data_cbm_aggregation_15_min WHERE virtual_id = 1818 AND ts >= '2015-02-01 00:00' AND ts < '2015-04-01 00:00' AND deleted IS NULL GROUP BY ts ORDER BY ts; > sum(230 * factor) – 将总和乘以一次而不是乘以每个元素会更便宜:sum(factor)* 230结果相同,即使是NULL值也是如此. 更好的指数,可能更大的改善 CREATE INDEX data_cbm_aggregation_15_min_special_idx ON data_cbm_aggregation_15_min (virtual_id,ts,amp,factor) WHERE deleted IS NULL; >我在你的问题中没有看到任何暗示你原始索引中的DESC的内容.虽然Index Scan Backward几乎与普通的Index Scan一样快,但删除修改器仍然更好. 表定义 像这样重新排序表列将每行节省8个字节: CREATE TABLE data_cbm_aggregation_15_min ( virtual_id integer NOT NULL,ts timestamp NOT NULL,min_amp_ts timestamp,max_amp_ts timestamp ); 有关: > Configuring PostgreSQL for read performance 最重要的信息 >对于非常大的表,第一次查询调用可能实质上更昂贵,因为整个表不能被缓存.后续调用从填充的缓存中获利. Postgres缓存块,不一定是整个表. > Why does a SELECT statement dirty cache buffers in Postgres? 关于你到目前为止所尝试的内容 > ts和virtual_id的SET STATISTICS 1000是一个很好的想法,但是通过设置random_page_cost = 1,效果基本上无效,这基本上强制对该查询进行索引扫描. 各个 >升级到Postgres 9.4(或即将推出的9.5,目前为alpha).版本9.2现在已经有3年了,最新版本已经获得了很多改进. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |