我有一个如下所示的 postgres 表:
CREATE UNLOGGED TABLE IF NOT EXISTS batch_update_data (
id TEXT DEFAULT gen_random_uuid()::TEXT
, account_id TEXT
, processed boolean
...
);
它有一个如下所示的索引:
CREATE INDEX batch_update_data__processed_false_idx ON batch_update_data(processed) WHERE processed = FALSE;
当我将数据批量加载到该表中时,我会立即运行如下查询:
SELECT
id,
...
FROM
batch_update_data
WHERE
processed = false
LIMIT
10
但是在我运行以下命令之前,这不会命中索引:
VACUUM ANALYZE public.batch_update_data;
我可以在日志中看到在批量加载期间真空正在运行,那么为什么在我手动运行它之前它没有命中索引?
我当前的自动真空设置如下:
"autovacuum" "on"
"autovacuum_analyze_scale_factor" "0.1"
"autovacuum_analyze_threshold" "50"
"autovacuum_freeze_max_age" "200000000"
"autovacuum_max_workers" "3"
"autovacuum_multixact_freeze_max_age" "400000000"
"autovacuum_naptime" "60"
"autovacuum_vacuum_cost_delay" "2"
"autovacuum_vacuum_cost_limit" "-1"
"autovacuum_vacuum_scale_factor" "0.2"
"autovacuum_vacuum_threshold" "50"
"autovacuum_work_mem" "-1"
"log_autovacuum_min_duration" "0"
您似乎没有在单个事务中运行批量加载,因此 autovacuum 或 autoanalyze 在加载数据的过程中启动。这意味着有两个选择:
在最后一次自动分析之后运行的批量加载部分修改了表的不到 10%,因此自动分析没有触发,并且最后加载值的统计信息很糟糕
ANALYZE
来解决。这是最佳实践,特别是如果您打算在批量加载后立即运行查询。