簡體   English   中英

Postgres JSONB 查詢簡化

[英]Postgres JSONB query simplification

我有一些工作代碼從表單表中提取記錄,其中 'mail@example.com' 在 JSONB 字段之一、 column_acolumn_bcolumn_ccolumn_d顯示為 JSON 值。

SELECT * 
FROM forms f
WHERE exists (SELECT * 
              FROM jsonb_each_text(f.column_a) as e(ky,val)
              WHERE e.val = 'mail@example.com')   
UNION

SELECT * 
FROM forms f
WHERE exists (SELECT * 
              FROM jsonb_each_text(f.column_b) as e(ky,val)
              WHERE e.val = 'mail@example.com')
UNION

SELECT * 
FROM forms f
WHERE exists (SELECT * 
              FROM jsonb_each_text(f.column_c) as e(ky,val)
              WHERE e.val = 'mail@example.com')
UNION

SELECT * 
FROM forms f
WHERE exists (SELECT * 
              FROM jsonb_each_text(f.column_d) as e(ky,val)
              WHERE e.val = 'mail@example.com');

列中的 JSON 類似於:

{ "xyz":"mail@example.com", "def":"mail2@example.com", "lmn":"mail3@example.com" }

盡管代碼有效,但它看起來高度重復/冗長。 鑒於我無法更改 JSON 結構,是否有更簡潔的方法來構建此查詢,以及我應該為這些列構建哪些索引以獲得最佳性能?

為什么不使用or

SELECT f.* 
FROM forms f
WHERE EXISTS (SELECT * 
              FROM jsonb_each_text(f.column_a) as e(ky,val)
              WHERE e.val = 'mail@example.com'
             ) OR
      EXISTS (SELECT * 
              FROM jsonb_each_text(f.column_b) as e(ky,val)
              WHERE e.val = 'mail@example.com'
             ) OR
      . . .

據推測,這也消除了重復消除的需要,因此查詢也應該更快。

編輯:

如果需要源,可以使用相關子查詢:

SELECT f.* 
FROM (SELECT f.*,
             EXISTS (SELECT * 
                     FROM jsonb_each_text(f.column_a) as e(ky,val)
                     WHERE e.val = 'mail@example.com'
                    ) as in_column_a,
             EXISTS (SELECT * 
                     FROM jsonb_each_text(f.column_b) as e(ky,val)
                     WHERE e.val = 'mail@example.com'
                    ) as in_column_b,
             . . .
      FROM forms f
     ) 
WHERE in_column_a OR in_column_b OR . . .

這不是很有效,因為它在找到匹配時不會短路評估。 另一方面,它列出了所有匹配的列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM