喂,
我正在编写一个数据库应用程序,它使用假serialisable
隔离级别(snapshot isolation
)执行大量插入和更新。
为了不进行大量的网络往返,我在PreparedStatement
s的一次交易中批量插入和更新。它们应该很少失败,因为插入是预先检查的,并且几乎没有冲突到其他事务,所以不经常发生回滚。
拥有大笔交易应该对WAL有利,因为它可以刷新大块而不必刷新小型交易。
1。)我只能看到大交易的积极影响。但我经常读到它们很糟糕。为什么他们的用例会不好?
2。)当local snapshots
合并回真实数据库时,检查冲突是否如此昂贵?数据库必须比较所有可能冲突的写集(并行事务)。还是它做了一些高速快捷方式?或者那是相当便宜的吗?
[ EDIT ]如果有人能够清楚地了解快照隔离数据库如何检查时间线上具有重叠部分的事务是否针对析取写集进行检查,那么这可能会很有趣。因为这就是伪序列化隔离级别的全部内容。
答案 0 :(得分:2)
这里真正的问题有两个方面。第一个可能的问题是膨胀。大型事务可能会导致很多死元组一次出现。另一个可能的问题是长时间运行的交易。只要长时间运行的事务正在运行,它触摸的表就不能被清理,所以也可以收集大量的死元组。
我想说使用check_postgresql.pl检查膨胀问题。只要你在长期交易后没有看到很多表膨胀,你就可以了。
答案 1 :(得分:1)
1)手册说它很好:http://www.postgresql.org/docs/current/interactive/populate.html
我还建议使用COPY,删除索引(但首先测试),增加maintenance_work_mem,增加checkpoint_segments,然后运行ANALYZE(或VACUUM ANALYZE)。
如果您不确定,我不会建议:删除外键约束,禁用WAL存档和流复制。
2)始终在提交时合并数据,但没有检查,只写入数据。再读一遍:http://www.postgresql.org/docs/current/interactive/transaction-iso.html
如果您的插入/更新不依赖于其他插入/更新,则不需要“完全一致的视图”。您可以使用read committed和transaction永远不会失败。