在postgresql中慢速提取json数组元素
发布时间:2020-12-13 15:54:40 所属栏目:百科 来源:网络整理
导读:我有一个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 fr
我有一个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只是为了应用补丁. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |