微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在postgresql中慢速提取json数组元素

我有一个json数组,我想将每个元素扩展到一个新表.使用 postgresql 9.3中的新json函数,我希望这是最好的方法

create table p as select json_array_elements(json) foo from g

令我惊讶的是,横向扩展速度要快得多:

create table p as select json->x foo from g join lateral (select 
generate_series(0,json_array_length(g.json)-1) x ) xxx on true

第一种方法的问题是什么?

编辑:测试用例可以为20000行构建

create table g as select (select json_agg(random()) json  from 
generate_series(0,(r1*4)::int))  from (select random() r1 from 
generate_series(1,20000)) aux;

通过SSD存储,横向需要3秒而0.2秒.对于40000行,时间增加到12秒,而横向方法刚好接近线性增长.

解决方法

测试用例肯定是决定性的,并且perf -p $the_backend_pid有助于说明原因:

96.92%  postgres      [.] MemoryContextReset
  0.15%  [kernel]      [k] cpuacct_account_field
  0.09%  [kernel]      [k] update_cfs_rq_blocked_load
  0.09%  postgres      [.] AllocSetAlloc
  0.09%  libc-2.17.so  [.] __memcpy_ssse3_back
  0.07%  postgres      [.] parse_array
  0.07%  [kernel]      [k] trigger_load_balance
  0.07%  [kernel]      [k] rcu_check_callbacks
  0.06%  [kernel]      [k] apic_timer_interrupt
  0.05%  [kernel]      [k] do_timer
  0.05%  [kernel]      [k] update_cfs_shares
  0.05%  libc-2.17.so  [.] malloc

它在MemoryContextReset中花费了大量时间.特别是鉴于上述情况在470亿事件(约)标记处被记录下来.

Backtraces总是如下:

#0  0x000000000072dd7d in MemoryContextReset (context=0x2a02dc90) at mcxt.c:130
#1  0x000000000072dd90 in MemoryContextResetChildren (context=<optimized out>) at mcxt.c:155
#2  MemoryContextReset (context=0x1651220) at mcxt.c:131
#3  0x00000000005817f9 in ExecScan (node=node@entry=0x164e1a0,accessMtd=accessMtd@entry=0x592040 <SeqNext>,recheckMtd=recheckMtd@entry=0x592030 <SeqRecheck>)
    at execScan.c:155

在MemoryContextReset中具有不同的位置,通常在分支处.

运行时间为836904.371,而对于200k输入行的横向连接,则为903.202(测试的10倍).

所以我说你肯定发现了需要注意的性能问题.

更新:here’s a patch将适用于git master或9.3.如果您正在使用Postgresql的deb / rpm包,那么很容易获取源包/ srpm并重建它,不需要切换到unpackaged只是为了应用补丁.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐