使用 Postgres SQL,模拟单行 UPSERT 最快的事务是什么?
这个问题是关于单行,而不是一组。我只是好奇使用最新最好的 Pg (9.0) 版本更快是什么以及为什么:
基于 PKEY 上的 SELECT 的条件更新或插入
尝试插入、捕获失败异常并回退到更新
尝试更新,在失败时捕获异常并回退到插入
我认为因为这个取决于数据集 让我们假设三种情况:
- 50% 的行存在, 50% 不存在
- 100% 的行存在
- 100% 的行不存在 存在
意味着 PKEY 满足并且该行应该被更新。任何有关这方面研究的链接都会很棒。
This question is about a single row, not a set. I'm just curious what is faster using the latest and greatest version of Pg (9.0) and why:
A conditional UPDATE or INSERT on the basis of a SELECT on the PKEYs
An attempt to INSERT, catch an exception on fail and falling back to an UPDATE
An attempt to UPDATE, catching an exception on fail and falling back to an INSERT
I think because this would depend on the dataset lets assume three scenarios:
- 50% of the rows are present, 50% aren't present
- 100% of the rows are present
- 100% of the rows aren't present
Presence means the PKEYs are satisfied and the row should be updated. Any links to research on this would be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一种情况永远不会比其他两种情况更快,因为您首先发出的 SELECT 是不必要的额外工作,并且也是由 UPDATE(也可能是 INSERT)隐式完成的。
即使使用 50% / 50% 的分布,我也认为使用 UPDATE/INSERT 会稍微快一些,因为错误处理(捕获异常)比不更新任何内容的 UPDATE 花费的时间要多得多。
因此,我会选择 UPDATE/INSERT 模式,除非您知道实际上不会有很多(例如 > 70%)的行。
但只有在您的环境中进行良好的性能测试才能证明这一点。
The first scenario will never be faster than the other two, because the SELECT that you issue first is unnecessary additional work and is done implicitely by UPDATE (and possibly INSERT) as well.
Even with a 50% / 50% percent distribution I'd think that using UPDATE/INSERT will slightly be faster as the error handling (catching the exception) takes considerably more time than an UPDATE that does not update anything.
So I'd go for the UPDATE/INSERT pattern unless you know that really a lot (e.g. > 70%) of rows won't be there.
But only a good performance test in your environment can tell that.
在 postgres 9.5 中,可以执行实际的 upsert:
http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=168d5805e4c08bed7b95d351bf097cff7c07dd65
In postgres 9.5, it will be possible to perform an actual upsert:
http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=168d5805e4c08bed7b95d351bf097cff7c07dd65