【发布时间】:2012-10-25 10:45:49
【问题描述】:
我在 Postgres 数据库上的 SELECT 查询中遇到了速度问题。
我有一个表,其中有两个整数列作为键:(int1,int2) 该表有大约 7000 万行。
我需要在这个环境中进行两种简单的 SELECT 查询:
SELECT * FROM table WHERE int1=X;
SELECT * FROM table WHERE int2=X;
这两个选择返回这 7000 万行中的大约 10.000 行。为了尽可能快地工作,我考虑使用两个 HASH 索引,每列一个。不幸的是,结果不是那么好:
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on lec_sim (cost=232.21..25054.38 rows=6565 width=36) (actual time=14.759..23339.545 rows=7871 loops=1)
Recheck Cond: (lec2_id = 11782)
-> Bitmap Index Scan on lec_sim_lec2_hash_ind (cost=0.00..230.56 rows=6565 width=0) (actual time=13.495..13.495 rows=7871 loops=1)
Index Cond: (lec2_id = 11782)
Total runtime: 23342.534 ms
(5 rows)
这是其中一个查询的 EXPLAIN ANALYZE 示例。大约需要 23 秒。我的期望是在不到一秒的时间内获得这些信息。
这些是 postgres db 配置的一些参数:
work_mem = 128MB
shared_buffers = 2GB
maintenance_work_mem = 512MB
fsync = off
synchronous_commit = off
effective_cache_size = 4GB
非常感谢任何帮助、评论或想法。
提前谢谢你。
【问题讨论】:
-
作为您总时间的一部分,其中有多少是将数据发回给您?您是在与数据库相同的机器上运行查询还是通过网络进行查询?
-
@JustBob:解释输出中报告的时间是在服务器上准备查询的时间(没有客户端往返)
-
哈希索引在 PostgreSQL 中效率不高。您是否尝试过常规的 B-Tree 索引?每一列都有一个索引,还是两者都有一个组合索引?这两个语句中的哪一个是发布的执行计划?
-
这里的索引查找非常快——所有时间都花在检索实际行上。 23 秒 / 7871 行 = 每行 2.9 毫秒,这对于检索分散在磁盘子系统中的数据是合理的。搜索很慢;您可以 a) 将数据集放入 RAM,b) 购买 SSD,或 c) 提前组织数据以尽量减少搜索。
-
两个表是一个选项,特别是如果你
CLUSTER两个表。但是,PostgreSQL 9.2 添加了一个名为index only scans 的功能,这在这里特别有用——在所有感兴趣的列上创建一个btree索引(PostgreSQL 自动保持有序),并且可以(可能)使用来回答查询只有没有额外搜索的索引。
标签: sql performance postgresql postgresql-performance