我在Postgres数据库的SELECT查询中遇到了速度问题.

我有一个表,有两个整数列作为键:(int1,int2)

在此环境中,我需要进行两种简单的SELECT查询:

SELECT * FROM table WHERE int1=X;
SELECT * FROM table WHERE int2=X;

这两个 Select 在这7000万行中返回大约10000行.为了让它尽可能快地工作,我考虑使用两个哈希索引,每列一个.不幸的是,结果并不是那么好:

                                                               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)

这是其中一个查询的解释分析示例.大约需要23秒.我的期望是在不到一秒钟内得到这些信息.

以下是postgres db配置的一些参数:

work_mem = 128MB
shared_buffers = 2GB
maintenance_work_mem = 512MB
fsync = off
synchronous_commit = off
effective_cache_size = 4GB

任何帮助、 comments 或 idea 都将不胜感激.

提前谢谢你.

推荐答案

将我的 comments 提取到一个答案中:这里的索引查找非常快——所有的时间都花在检索实际的行上.23秒/7871行=每行2.9毫秒,这对于检索分散在磁盘子系统中的数据是合理的.寻找缓慢;您可以a)将数据集放入RAM中,b)购买SSD,或c)提前组织数据以最小化搜索.

PostgreSQL 9.2有一个名为index-only scans的功能,允许它(通常)在不访问表的情况下回答查询.您可以将其与自动维护顺序的btree index属性相结合,以使此查询快速进行.您提到int1int2和两个浮动:

CREATE INDEX sometable_int1_floats_key ON sometable (int1, float1, float2);
CREATE INDEX sometable_int2_floats_key ON sometable (int2, float1, float2);

SELECT float1,float2 FROM sometable WHERE int1=<value>; -- uses int1 index
SELECT float1,float2 FROM sometable WHERE int2=<value>; -- uses int2 index

还要注意的是,这并不会神奇地擦除磁盘搜索,它只是将它们从查询时间移动到插入时间.由于要复制数据,因此还需要占用存储空间.不过,这可能是你想要的权衡.

Postgresql相关问答推荐

使用regexp获取表名

PostgreSQL\d命令:有办法只 Select 一列吗?

使用Helm设置PostgreSQL配置

如何重新格式化已获取的 psql 查询输出?

如何在不同的行中显示两列,避免重复并省略空条目

Postgres 将分区附加到表的时间太长.想明白为什么

使用包含重复元素的数组 Select 重复值

使用 JDBC 连接到 PostgreSql 的本地实例

如何在 Sequelize ORM 中插入 PostGIS GEOMETRY 点?

PostgreSQL 错误:42P01:relation "[Table]" does not exist

sql:转换参数 $1 类型:不支持的类型 []int,in 的一部分

推送到 Heroku 时出现带有 Postgres 的 Rails 迁移错误

Heroku PGError:operator does not exist: character varying = integer

如何在 Postgresql 中正确使用 FETCH FIRST?

Postgresql:在插入列时(或之前)自动小写文本

具有 DEFAULT NULL 的 MySQL 列 ?

如果 PostgreSQL count(*) 总是很慢,如何对复杂查询进行分页?

使用 Postgres 在 Rust 的 Diesel 库中添加时间戳

基于秒的 Postgresql 日期差异

如何为 adminpack 解决 PostgreSQL pgAdmin 错误Server instrumentation not installed?