我想知道,在 PostgreSQL 中完成此类任务的最快方法是什么。我对最快的解决方案感兴趣。
我发现自己有这样一种 MySQL 解决方案,它的执行速度比一张一张地截断表要快得多。但无论如何,我也对最快的 MySQL 解决方案感兴趣。在这里查看我的结果,当然它仅适用于 MySQL:https ://github.com/bmabey/database_cleaner/issues/126
我有以下假设:
- 我有 30-100 张桌子。让他们30岁。
- 一半的桌子是空的。
- 例如,每个非空表的行数不超过 100 行。我的意思是,桌子并不大。
我需要一个可选的可能性来从这个过程中排除 2 个或 5 个或 N 个表。
我不能!使用事务。
对于在 PostgreSQL 8 和 9 上工作的这种情况,我需要最快的清理策略。
我看到以下方法:
截断每个表。我认为这太慢了,尤其是对于空桌子。
用更快的方法检查每个表是否为空,如果为空,则将其唯一标识符列(类似于 MySQL 中的 AUTO_INCREMENT)重置为初始状态(1),即将其 last_value 从序列恢复为 1,否则运行 truncate在上面。
我使用 Ruby 代码遍历所有表,在每个表上调用下面的代码,我尝试设置针对每个表运行的 SQL 代码,例如:
DO $$DECLARE r record;
BEGIN
somehow_captured = SELECT last_value from #{table}_id_seq
IF (somehow_captured == 1) THEN
== restore initial unique identifier column value here ==
END
IF (somehow_captured > 1) THEN
TRUNCATE TABLE #{table};
END IF;
END$$;
在各个方面操作这段代码,我无法让它工作,因为我不熟悉 PostgreSQL 函数和块(和变量)。
另外我的猜测是 EXISTS(SELECT something FROM TABLE) 可以以某种方式用作“检查程序”单元之一,清洁程序应该包括但还没有完成。
我将不胜感激有关如何以 PostgreSQL 本机方式完成此过程的任何提示。
更新:
我需要所有这些来为 Ruby 或 Ruby on Rails 项目运行单元和集成测试。每个测试在运行之前都应该有一个干净的数据库,或者在其自身之后进行清理(所谓的拆卸)。事务非常好,但是在针对特定 web 驱动程序运行测试时它们变得不可用,在我的情况下,需要切换到截断策略。一旦我参考 RoR 进行了更新,请不要在此处发布有关“显然,您需要 DatabaseCleaner for PG”等的答案。
更新 2:
最近这里描述的策略被合并到 DatabaseCleaner,https ://github.com/bmabey/database_cleaner 作为 :pre_count 选项(参见那里的自述文件)。