HI
我有一个表格,其中包含文件及其类型,例如
CREATE TABLE files (
id SERIAL PRIMARY KEY,
name VARCHAR(255),
filetype VARCHAR(255),
...
);
和另一个用于保存文件属性的表,例如
CREATE TABLE properties (
id SERIAL PRIMARY KEY,
file_id INTEGER CONSTRAINT fk_files REFERENCES files(id),
size INTEGER,
... // other property fields
);
file_id字段有一个索引。
文件表有大约800k行,属性表大约200k(并非所有文件都必须具有/需要属性)。
我想进行聚合查询,例如查找所有文件类型的平均大小和标准差。但它非常慢 - 后者查询大约70秒。我知道它需要顺序扫描,但看起来仍然太多了。 这是查询
SELECT f.filetype, avg(size), stddev(size) FROM files as f, properties as pr
WHERE f.id = pr.file_id GROUP BY f.filetype;
和解释
HashAggregate (cost=140292.20..140293.94 rows=116 width=13) (actual time=74013.621..74013.954 rows=110 loops=1)
-> Hash Join (cost=6780.19..138945.47 rows=179564 width=13) (actual time=1520.104..73156.531 rows=179499 loops=1)
Hash Cond: (f.id = pr.file_id)
-> Seq Scan on files f (cost=0.00..108365.41 rows=1140941 width=9) (actual time=0.998..62569.628 rows=805270 loops=1)
-> Hash (cost=3658.64..3658.64 rows=179564 width=12) (actual time=1131.053..1131.053 rows=179499 loops=1)
-> Seq Scan on properties pr (cost=0.00..3658.64 rows=179564 width=12) (actual time=0.753..557.171 rows=179574 loops=1)
Total runtime: 74014.520 ms
任何想法为何如此缓慢/如何让它更快?
答案 0 :(得分:1)
我不知道postgressql但是我
filetype
有一个索引,可能是filetype和id的覆盖索引。SQL声明
SELECT f.filetype
, avg_size
, stddev_size
FROM files as f
INNER JOIN (
SELECT file_id
, avg(size) as avg_size
, stddev(size) as stddev_size
FROM properties
GROUP BY
file_id
) p ON p.file_id = f.id
答案 1 :(得分:1)
您是否为服务器参数定义了合理的设置,例如shared_buffers,work_mem和effective_cache_size? http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
特别是,我认为work_mem会影响连接的哈希表有多少可以保留在内存中而不是磁盘上。此外,减少random_page_cost可能会影响规划人员使用合并连接 - 尝试暂时将“enable_hashjoin”设置为关闭并查看是否会产生更好的计划?