簡體   English   中英

Postgres JSONB-在兩個JSON字段之間進行聯接

[英]Postgres JSONB - join between two JSON fields

使用Postgres 9.5,如何查詢帶有JSONB列,聯接兩個JSON字段,關鍵地利用GIN索引來最大化性能的表?

我正在為一個系統制作原型,該系統可以在一個平台上為不同的客戶提供不同的模式/數據模型。 實體屬性值(EAV)是這種情況的一種常見模式,我熱衷於對Postgres如何處理使用其JSONB數據類型存儲的實體的查詢進行基准測試。

我有一個表,用於存儲不同類型的實體,例如客戶,銷售交易。

CREATE TABLE entity_jsonb (
    id uuid PRIMARY KEY,
    type text,
    created_at timestamp without time zone,
    properties jsonb,
    org_id integer
);
CREATE INDEX entity_jsonb_created_at_idx ON entity_jsonb USING btree (created_at);
CREATE INDEX entity_jsonb_org_id_idx ON entity_jsonb USING btree (org_id);
CREATE INDEX entity_jsonb_type_idx ON entity_jsonb USING btree (type);
CREATE INDEX entity_jsonb_properties_idx ON entity_jsonb USING gin (properties);

我在此表中有一條具有'customer'類型和屬性的客戶記錄:

{"uuid": "8f8896c7-f41c-49f7-ad6e-4613f7b51a23", "email": "crashfound@somema1l.org", "lastname": "McCarthy", "createdAt": "May 27, 2015 12:06:45 PM", "firstname": "Nathan"}

我在此表中具有類型為'sales_transaction'和屬性的銷售交易記錄:

{"uuid": "54243d48-e69f-4bb6-ab33-6defb8a0f626", "amount": 99817, "status": 0, "paymentType": 1, "currencyCode": "USD", "customerUuid": "8f8896c7-f41c-49f7-ad6e-4613f7b51a23", "transactionId": "471170"}

我如何利用GIN索引(運算符:@>,?,?&、? |)來高效地查詢交易,但是如何與客戶一起從這兩者返回數據,例如填充最近7天的交易列表,客戶名稱以及交易金額?

我試過這個查詢來查找交易對象(金額= 99817)和相關客戶詳細信息的子集:

SELECT t.properties AS transaction, c.properties AS customer 
FROM entity_jsonb t 
JOIN entity_jsonb c ON (c.properties->>'uuid' = t.properties->>'customerUuid' AND c.type = 'customer') 
WHERE t.type = 'sales_transaction' AND t.properties @> '{"amount" : 99817}';

它可以工作,但是不使用GIN索引,即不如我希望的那樣快。 我嘗試了這種方法(使用GIN @>包含運算符),但其中不包含客戶詳細信息。 我究竟做錯了什么?

SELECT t.properties AS transaction, c.properties AS customer FROM entity_jsonb t LEFT JOIN entity_jsonb c ON (c.properties @> json_build_array(json_build_object('uuid', t.properties->'customerUuid'))::jsonb AND c.type = 'customer') WHERE t.type = 'sales_transaction' AND t.properties @> '{"amount" : 99817}';

我知道與傳統的關系設計相比,這不是最佳解決方案,但是我很想知道查詢將純實體數據存儲為JSON的效率如何。

我的查詢距離不遠。 我不需要json_build_array 對於10萬個客戶的數據集,查詢現在的運行速度比不使用GIN索引的版本快10倍:

SELECT t.properties AS transaction, c.properties AS customer 
FROM entity_jsonb t 
JOIN entity_jsonb c ON (c.properties @> json_build_object('uuid', t.properties->'customerUuid')::jsonb AND c.type = 'customer') 
WHERE t.type = 'sales_transaction' AND t.properties @> '{"amount" : 99817}';

暫無
暫無

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

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