Pra*_*thi 5 java json postgresql-performance jsonb postgresql-9.4
第一次尝试使用JSONB数据类型(从(从JSONB列中的值联接表开始)讨论@Erwin的意见,开始新线程)
两个表(混淆的数据和表名):
1. Discussion table { discussion_id int, contact_id, group_id, discussion_updates jsonb } [has around 600 thousand rows]
2. Authorization table {user_id varchar , auth_contacts jsonb, auth_groups jsonb} [has around 100 thousand rows]
auth_contacts jsonb data has key value pairs data (as example)
- {"CC1": "rr", "CC2": "ro" }
auth_groups jsonb data has key value pairs data (as example)
- {"GRP1": "rr", "GRP2": "ro" }
Run Code Online (Sandbox Code Playgroud)
1-首先,通过Java JDBC在数据库中插入:我正在做的是:
JSONObject authContacts = new JSONObject();
for(each record in data){
authContacts.put(contactKey, contactRight);
authGroups.put(groupKey, groupRight);
}
String insertSql = "INSERT INTO SSTA_AuthAll(employee_id, auth_contacts, auth_groups) VALUES(?,?::jsonb,?::jsonb)";
//---Connect to Db and prepare query
preparedStatement.setObject(2, authContacts.toJSONString());
preparedStatement.setObject(3, authGroups.toJSONString());
//INSERT into DB
Run Code Online (Sandbox Code Playgroud)
现在,toJSONString()花费时间(有时长达1秒-TIME FOR toJSON STRING LOOP:17238ms),这仍然是低效的。那么这又是正确的方法吗?Google上的大多数示例都直接插入了一个字符串。
如果我将MAP直接插入到jsonb coolumn中,它会期望一个HSTORE扩展名,如果我打算使用jsonb,这是我不应该使用的扩展名?
2-现在在下一部分:我需要将讨论表中的contact_id与auth_contacts json数据类型的contact_id [这是如上例中所示的键]结合起来,并将auth_groups的group_id与讨论表的group_id结合起来
截至目前为止,仅尝试在contact_id上加入:
SELECT *
FROM discussion d
JOIN
(SELECT user_id, jsonb_object_keys(a.contacts) AS contacts FROM auth_contacts a WHERE user_id='XXX') AS c
ON (d.contact_id = c.contacts::text)
ORDER BY d.updated_date DESC
Run Code Online (Sandbox Code Playgroud)
对于拥有约6万个授权联系人的用户,这种连接大约需要60毫秒,而连续运行的时间要短一些-混淆的说明计划如下:
"Sort (cost=4194.02..4198.39 rows=1745 width=301) (actual time=50.791..51.042 rows=5590 loops=1)"
" Sort Key: d.updated_date"
" Sort Method: quicksort Memory: 3061kB"
" Buffers: shared hit=11601"
" -> Nested Loop (cost=0.84..4100.06 rows=1745 width=301) (actual time=0.481..44.437 rows=5590 loops=1)"
" Buffers: shared hit=11598"
" -> Index Scan using auth_contacts_pkey on auth_contacts a (cost=0.42..8.93 rows=100 width=888) (actual time=0.437..1.074 rows=1987 loops=1)"
" Index Cond: ((user_id)::text = '105037'::text)"
" Buffers: shared hit=25"
" -> Index Scan using discussion_contact_id on discussion d (cost=0.42..40.73 rows=17 width=310) (actual time=0.016..0.020 rows=3 loops=1987)"
" Index Cond: ((contact_id)::text = (jsonb_object_keys(a.contacts)))"
" Buffers: shared hit=11573"
"Planning time: 17.866 ms"
"Execution time: 52.192 ms"
Run Code Online (Sandbox Code Playgroud)
我的最终目标是在同一查询中使用group_id进行附加连接。jsonb_object_keys所做的实际上是为每个密钥创建一个userid vs authcontacts映射。因此,对于具有6万个联系人的用户,它将创建6万行的视图(可能在内存中)。现在,如果我在auth_groups上包括join(对于具有6万个联系人的示例用户,它将有大约10万个组,这会使查询变慢。
那么这是在jsonb对象上进行联接的正确方法吗,还有更好的方法吗?