Postgres缓慢查询多列的独特查询

时间:2017-07-12 00:12:38

标签: postgresql performance

我有一个非常简单的查询,运行时间过长。

SELECT DISTINCT col1,col2,col3,col4 FROM tbl1;

我需要添加哪些索引才能加快速度?我运行了一个简单的vacuum;命令并添加了以下索引但没有帮助。

CREATE INDEX tbl_idx ON tbl1(col1,col2,col3,col4);

该表有400k行。事实上,计算它们也需要很长时间。运行一个简单的

SELECT count(*) from tbl1;

需要8秒钟。所以我的问题可能是吸尘或重新索引或者我不确定的事情。

这是解释命令

EXPLAIN SELECT DISTINCT col1,col2,col3,col4 FROM tbl1;
                                   QUERY PLAN                                    
---------------------------------------------------------------------------------
 Unique  (cost=3259846.80..3449267.51 rows=137830 width=25)
   ->  Sort  (cost=3259846.80..3297730.94 rows=15153657 width=25)
         Sort Key: col1, col2, col3, col4
         ->  Seq Scan on tbl1 (cost=0.00..727403.57 rows=15153657 width=25)
(4 rows)

编辑:我目前正在运行vacuum full;,希望能解决问题,然后有人可以给我一些关于如何解决我出错的问题。这是几个小时,我仍然可以告诉你。我确实跑了

select relname, last_autoanalyze, last_autovacuum, last_vacuum, n_dead_tup from pg_stat_all_tables where n_dead_tup >0;

并且该表有近1600万个n_dead_tup行。

3 个答案:

答案 0 :(得分:1)

我的数据并没有经常改变,所以我最终创建了物化视图

CREATE MATERIALIZED VIEW tbl1_distinct_view AS SELECT DISTINCT col1,col2,col3,col4 FROM tbl1;

我每天早上6点用cronjob刷新一次

0 6 * * * psql -U mydb mydb -c 'REFRESH MATERIALIZED VIEW tbl1_distinct_view;

答案 1 :(得分:0)

VACUUMVACUUM FULL是两个听起来相同但效果却截然不同的命令。

VACUUM会扫描一个表,查找它不再需要的元组,以便它可以在INSERTUPDATE语句中覆盖该空格。此命令仅查看已删除的行,并且" defragment"表 - 它使空间使用相同,但只是标记一些空间为"死"以便它可以重复使用。

VACUUM FULL查看每个行,并回收已删除的行和死元组留下的空间,基本上是" defragmenting"桌子。如果在实时表上执行此操作,则可能需要很长时间,并且可能导致重量级锁定,IO增加和索引膨胀。

我认为您需要的是VACUUM后跟ANALYZE,它将重建每个表的统计信息,从而提高索引性能。这些应该在数据库的低使用时间内合理地定期执行。只有当你有足够的空间来回收时(由于很多DELETE语句)你应该使用VACUUM FULL

无论如何,既然您已经运行了VACUUM FULL,那么一旦完成,您应该在数据库上运行ANALYZE,然后在数据库上运行REINDEX,然后再次查询EXPLAIN,您应该注意到有所改进。

答案 2 :(得分:0)

尝试使用数据库来使用索引

set enable_seqscan=off ;
SELECT DISTINCT col1,col2,col3,col4 FROM tbl1;
set enable_seqscan=on ;