使用postgresql 9.4我们有一个简单的联系人表(id文本不为null(作为pk),blob json)来试验移植couchdb crm数据库.我们最终将拆分为更多的列等,并为rdbms更自觉地处理数据,但这是暂时的.
大约有100k行.
我知道硬核postgresql性能专家建议不要使用偏移但是我可以接受一个小的性能惩罚(对100毫秒以下的任何东西都满意)
SELECT id FROM couchcontacts OFFSET 10000 LIMIT 10
Run Code Online (Sandbox Code Playgroud)
如预期的那样需要<10ms
SELECT blob->>'firstName' FROM couchcontacts LIMIT 10
Run Code Online (Sandbox Code Playgroud)
也需要<10ms(在这里假设blob列上有10个json解码操作)
SELECT blob->>'firstName' FROM couchcontacts OFFSET 10000 LIMIT 10
Run Code Online (Sandbox Code Playgroud)
需要10秒钟!忽略偏移的低效率为什么这可能导致10,010个json解码操作?由于投影没有副作用,我不明白这不能快的原因?
这是json功能的限制对postgres来说相对较新吗?因此无法确定操作者->>
不会产生副作用?
有趣的是将查询重写为10毫秒以下
SELECT jsonblob->>'firstName' FROM couchdbcontacts WHERE id IN (SELECT id FROM couchcontacts OFFSET 10000 LIMIT 10)
Run Code Online (Sandbox Code Playgroud)
有没有办法确保偏移不json解码偏移的记录?(即不执行选择投影)
"Limit (cost=1680.31..1681.99 rows=10 width=32) (actual time=12634.674..12634.842 rows=10 loops=1)"
" -> Seq Scan on couchcontacts (cost=0.00..17186.53 rows=102282 width=32) (actual time=0.088..12629.401 rows=10010 loops=1)"
"Planning time: 0.194 ms"
"Execution time: 12634.895 ms"
Run Code Online (Sandbox Code Playgroud)
我跑了几个测试,我看到了类似的行为.这些中的每一个都在性能方面存在非重大差异:
select id
...select indexed_field
...select unindexed_field
...select json_field
...select *
...但是,这个确实显示出性能上的差异:
select json_field->>'key'
...当json_field为null时,性能影响可以忽略不计.如果它是空的,它会稍微降低一些东西.当它被填满时,它会明显降低.当字段加载更大的数据时,它会大幅降低.
换句话说,Postgres似乎想要为它访问的每一行重新序列化json数据.(这可能是一个错误,并且正在大量影响RoR开发人员看到他们如何使用json.)
Fwiw,我注意到重新安排查询以便它使用CTE将解决问题:
with data as (
select * from table offset 10000 limit 10
)
select json_field->>'key' from data;
Run Code Online (Sandbox Code Playgroud)
(它可能会得到一个比id IN (...)
你突出显示的查询更好的计划.)
归档时间: |
|
查看次数: |
758 次 |
最近记录: |