5

第一次尝试 JSONB 数据类型(根据@Erwin 的建议,从(使用 JSONB 列中的值连接表)继续讨论,开始新线程)

两个表(混淆数据和表名):

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" }

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

现在,toJSONString() 需要时间(有时长达 1 秒 - toJSON STRING LOOP:17238ms 的时间),这又是低效的。那么这又是正确的方法吗?google 上的大多数示例都直接插入了一个字符串。

如果我直接将 MAP 插入 jsonb coolumn ,它需要一个 HSTORE 扩展,如果我要使用 jsonb,我不应该使用它吗?

2-现在在下一部分:我需要将讨论表中的contact_id与auth_contacts json数据类型的contact_id [如上例所示的关键]并用讨论表的group_id加入auth_groups的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

对于拥有大约 60,000 个授权联系人的用户,此加入大约需要 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"

我的最终目标是使用 group_id 在同一个查询中额外加入。jsonb_object_keys 所做的实际上是为每个键创建一个 userid vs authcontacts 映射。因此,对于拥有 6 万联系人的用户,它将创建一个包含 6 万行的视图(可能在内存中)。现在,如果我在 auth_groups 上加入 join (对于具有 6 万联系人的示例用户,它将有大约 100 万个组,这会使查询变慢。

那么这是加入 jsonb 对象的正确方法吗?有更好的方法吗?

4

0 回答 0