Postgres查询优化

时间:2015-06-26 12:12:58

标签: sql postgresql indexing

在我们的数据库中,我们有一个包含515502行的表menus。它有一个status列,smallint

目前,对于status值为3的文档集,简单计数查询需要700毫秒。

explain analyze select count(id) from menus where status = 2;
Aggregate  (cost=72973.71..72973.72 rows=1 width=4) (actual time=692.564..692.565 rows=1 loops=1)
->  Bitmap Heap Scan on menus  (cost=2510.63..72638.80 rows=133962 width=4) (actual time=28.179..623.077 rows=135429 loops=1)
         Recheck Cond: (status = 2)
         Rows Removed by Index Recheck: 199654
         ->  Bitmap Index Scan on menus_status  (cost=0.00..2477.14 rows=133962 width=0) (actual time=26.211..26.211 rows=135429 loops=1)
               Index Cond: (status = 2)
 Total runtime: 692.705 ms
(7 rows)

某些行的列值为1,查询运行速度非常快。

 explain analyze select count(id) from menus where status = 4;
                                                          QUERY PLAN                                                           
-------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=7198.73..7198.74 rows=1 width=4) (actual time=24.926..24.926 rows=1 loops=1)
   ->  Bitmap Heap Scan on menus  (cost=40.53..7193.53 rows=2079 width=4) (actual time=1.461..23.418 rows=2220 loops=1)
         Recheck Cond: (status = 4)
         ->  Bitmap Index Scan on menus_status  (cost=0.00..40.02 rows=2079 width=0) (actual time=0.858..0.858 rows=2220 loops=1)
               Index Cond: (status = 4)
 Total runtime: 25.089 ms
(6 rows)

我观察到最常见的btree索引是基于简单相等查询的最佳索引策略。 ginhash都比btree慢。

有关使用索引的任何过滤器更快地进行count查询的任何提示吗?

我知道这是一个初学者级别的问题,所以请提前为我可能犯过的任何错误道歉。

1 个答案:

答案 0 :(得分:0)

也许你的表有更多的行status = 2而不是status = 4的行,因此,第二种情况下的总表访问时间更长。 因此,对于status = 2,要考虑的行太多,因此位图堆扫描的位图将进入“有损”模式,并且在操作后需要重新检查。因此,有两件事需要考虑:要么你的结果太大(但是如果没有重组你的表,你就不能做任何事情,比如分区),或者你的' work_mem '参数是太小,不能保持间歇性的结果。如果有可能,尽量增加其价值。