【发布时间】:2012-07-10 07:07:21
【问题描述】:
我们使用Postgresql 9.1.4 作为我们的数据库服务器。我一直在努力加快我的测试套件的速度,所以我盯着数据库分析了一下,看看到底发生了什么。我们使用database_cleaner 在测试结束时截断表。是的,我知道交易速度更快,但在某些情况下我无法使用它们,所以我不担心。
我关心的是,为什么 TRUNCATION 需要这么长时间(比使用 DELETE 更长),以及为什么在我的 CI 服务器上需要更长的时间。
现在,在本地(在 Macbook Air 上)一个完整的测试套件需要 28 分钟。拖尾日志,每次我们截断表时......即:
TRUNCATE TABLE table1, table2 -- ... etc
执行截断需要 1 秒以上。在我们的 CI 服务器(Ubuntu 10.04 LTS)上跟踪日志,截断表需要整整 8 秒,构建需要 84 分钟。
当我切换到 :deletion 策略时,我的本地构建需要 20 分钟,而 CI 服务器下降到 44 分钟。这是一个显着的差异,我真的很惊讶为什么会这样。我在 CI 服务器上有 tuned the DB,它有 16gb 系统内存、4gb shared_buffers...和一个 SSD。所有的好东西。怎么可能:
a. 它比我的带有 2gb 内存的 Macbook Air 慢得多
b. 当postgresql docs 时,TRUNCATION 比 DELETE 慢得多state explicitly 应该更快。
有什么想法吗?
【问题讨论】:
-
你是在 macbook 上运行测试和数据库,在 CI 服务器上运行测试和数据库吗?测试和数据库是否在同一台机器上?
-
顺便说一句,你做错了......你无法在测试后清除数据库。您应该在运行测试之前执行此操作。您无法确定测试后数据库是否已清除。
-
使用了哪些 postgresql.conf 参数?我想知道您是否使用 fsync=off 运行(如果您不介意丢失所有数据,例如在测试中),在这种情况下,
DELETE和TRUNCATE之间的平衡可能会有所不同。我也对你的shared_buffers感兴趣。 -
当你的意思是“使用事务”时,你是指打开一个事务,做一些测试,然后回滚吗?因为在我看来,这只是测试的一半。如果您使用
SERIALIZABLE事务、DEFERRABLE INITIALLY DEFERRED约束等,那么在COMMIT时间会发生很多事情,提交测试更改似乎是明智的。 -
顺便说一句,“etc”有多长,即一次有多少表被截断?它们是非常小的表,还是包含一些数据?如果小表比
TRUNCATE更快DELETE FROM,我不会感到太震惊,因为TRUNCATE必须分配一个新的支持文件,写入标题,用它交换旧的,刷新缓冲区缓存对于表,和fsync。我怀疑文档可能需要更新以反映TRUNCATE使用大表要快得多,但不一定是小/空的。
标签: postgresql database-performance truncate