jef*_*fjv 6 django postgresql heroku
我有一个在Django项目中运行Heroku的Postgres 9.4.18数据库.我注意到查询变得越来越慢所以我在一个查询上运行了"EXPLAIN ANALYZE"并注意到对于一个节点,行估计大大高于实际行数:
-> Seq Scan on listings_listing u1 (cost=0.00..1536692.01 rows=5030003 width=8) (actual time=0.811..11263.410 rows=173537 loops=1)
Run Code Online (Sandbox Code Playgroud)
然后我在桌面上运行"VACUUM FULL ANALYZE",然后在查询中重新启用"EXPLAIN ANALYZE"并得到:
-> Seq Scan on listings_listing u1 (cost=0.00..23554.61 rows=173537 width=8) (actual time=0.001..33.884 rows=173537 loops=1)
Run Code Online (Sandbox Code Playgroud)
现在执行时间快了100倍.
所以这两个问题是:A)不应该自动吸尘是否会阻止这种情况?(如何检查是否已启用?)B)假设未执行抽真空,它是如何实现的?
---------------------------------更新
我从heroku发现了这个命令,它给出了autovacuum stats,这里是输出(不幸的是我在手动真空后运行它.
heroku pg:vacuum_stats DATABASE_URL
schema | table | last_vacuum | last_autovacuum | rowcount | dead_rowcount | autovacuum_threshold | expect_autovacuum
--------+-----------------------------------------+-------------+------------------+----------------+----------------+----------------------+-------------------
public | listings_listing | | 2018-06-27 15:36 | 173,537 | 0 | 34,757 |
Run Code Online (Sandbox Code Playgroud)
似乎所指示的阈值应该导致它在很久以前运行真空.
此外,这里是关于吸尘设置文档的Heroku页面:https: //devcenter.heroku.com/articles/managing-vacuum-on-heroku-postgres
要查明是否已启用自动抽真空,请运行
SHOW autovacuum;
Run Code Online (Sandbox Code Playgroud)
要了解您的特定表是否禁用了自动抽真空,请运行
SELECT reloptions FROM pg_class WHERE relname = 'listings_listing';
Run Code Online (Sandbox Code Playgroud)
B)的答案很简单:
如果autovacuum没有运行,则每个UPDATE或DELETE都会在表中创建一个“死元组”(或“死行版本”)。除非您VACUUM手动运行这些文件,否则它们将永远不会被清除,这将导致表增长,从而使顺序扫描变得更慢。
A)的答案更加困难:
有几件事可以阻止自动真空工作:
该表的更改速率可能很高,默认情况下自动运行的速度很慢,因此不会干扰正常活动,因此无法跟上。
在这种情况下,您应该调整自动真空度以使该表更具攻击性:
ALTER TABLE listings_listing SET (
autovacuum_vacuum_cost_limit = 1000,
toast.autovacuum_vacuum_cost_limit = 1000
);
Run Code Online (Sandbox Code Playgroud)
如果那还不够好,您可以
ALTER TABLE listings_listing SET (
autovacuum_vacuum_cost_delay = 0,
toast.autovacuum_vacuum_cost_delay = 0
);
Run Code Online (Sandbox Code Playgroud)有并发的长事务。
Autovacuum只能删除比最旧的正在运行的事务更早的死元组,因此长时间的事务会使它无法执行其工作。
故事还有更多;阅读此博客文章。
但是,这也将使其VACUUM (FULL)无法继续工作,因此也许这不是您的问题。
该表经常用SHARE UPDATE EXCLUSIVE或更强的锁锁定,例如通过运行“ LOCK listings_listing”。
当自动真空遇到这种锁定时,它会后退而不是阻止用户活动。
确定正在发生什么情况的一种有用方法是如下查询pg_stat_user_tables:
SELECT n_live_tup, n_dead_tup, last_vacuum, last_autovacuum
FROM pg_stat_user_tables
WHERE relname = 'listings_listing';
Run Code Online (Sandbox Code Playgroud)
但是,既然您已经逃跑了,那证据可能就被摧毁了VACUUM (FULL)。
要做的另一件事是将值设置log_autovacuum_min_duration为-1以外的值,并偶尔查看日志。
| 归档时间: |
|
| 查看次数: |
268 次 |
| 最近记录: |