我有一个非常简单的查询,运行时间过长。
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行。
答案 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)
VACUUM
和VACUUM FULL
是两个听起来相同但效果却截然不同的命令。
VACUUM
会扫描一个表,查找它不再需要的元组,以便它可以在INSERT
或UPDATE
语句中覆盖该空格。此命令仅查看已删除的行,并且不" 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 ;