【发布时间】:2014-03-12 20:35:44
【问题描述】:
我使用 PL/pgSQL 编写了一个脚本,在 pgAdmin III 中运行。该脚本删除现有的数据库内容,然后为所需的测试场景(通常是各种类型的负载测试)添加一堆“样本”数据。加载数据后,我想对受影响的表进行“真空分析”,以从已删除的记录中恢复空间并准确反映新内容。
我可以使用各种解决方法(例如,手动执行 VACUUM ANALYZE,在脚本中包含用于各种结构的 drop/create 语句等)但是,我真正想做的是:
DO $$
BEGIN
-- parent table
FOR i IN 1..10000 LOOP
INSERT INTO my_parent_table( ... ) VALUES ...;
END LOOP;
VACUUM ANALYZE my_parent_table;
-- child table
FOR i IN 1..50000 LOOP
INSERT INTO my_child_table( ... ) VALUES ...;
END LOOP;
VACUUM ANALYZE my_child_table;
END;
$$;
当我运行它时,我得到:
ERROR: VACUUM cannot be executed from a function or multi-command string
然后我尝试像这样将真空语句移到末尾:
DO $$
BEGIN
-- parent table
FOR i IN 1..10000 LOOP
INSERT INTO my_parent_table( ... ) VALUES ...;
END LOOP;
-- child table
FOR i IN 1..50000 LOOP
INSERT INTO my_child_table( ... ) VALUES ...;
END LOOP;
END;
$$;
VACUUM ANALYZE my_parent_table;
VACUUM ANALYZE my_child_table;
这给了我同样的错误。有什么方法可以将真空分析合并到添加数据的同一脚本中?
我正在使用 PostgreSQL v 9.2。
【问题讨论】:
-
批量insert 之后就不需要真空了。仅当您删除或更新大量数据时才需要vacuum(因为它会回收不再需要的空间)。在您的情况下,
analyze本身就足够了。 -
谢谢,但我真的想要“真空分析”;在为所需的测试场景添加新数据之前,脚本首先删除所有现有数据。我已经编辑了这个问题以明确这一点。
-
如果您的脚本首先删除所有现有数据,也许您应该截断表,从而避免需要清理。
-
除了 jjanes 答案之外,在
delete(或truncate)之后执行vacuum analyzebeforeinsert将是瞬间的。 -
This answer on dba.stackexchange 为我解决了这个问题:在您的函数中调用
ANALYZE,但将其留给 autovacuum 以优雅地释放空间(只需确保您已为您的大桌子)。
标签: postgresql postgresql-9.2 database-administration