Postgresql
在 SELECT 查詢中加入外部數據
我有幾個(~20)產品名稱對應於一個整數 id,在導出產品數據(使用)時需要加入產品
COPY (<query>) TO
。負擔是這些名稱不在 DB 中,而是在 Redis 中(rails 的翻譯僅供參考)。因此,我將在每次導出之前收集這些名稱。現在,在數據庫之外擁有這些名稱,我如何建構查詢來加入它們?我試圖即時加入這些名稱:
SELECT ... LEFT JOIN ( SELECT unnest('{1,2,3}'::int[]) AS id, unnest($${"name1", "name2", "name3"}$$::text[]) AS name ) AS product_names ON product_names.id = products.type_id ...
但是我已經被產品行的數量(~500k)和缺乏該結構的索引所困擾。是否有一些(更好的)方法可以即時加入這些數據?我想雖然不能索引這些即時數據。
哪個是解決這種情況的好方法?我可以考慮創建臨時表,例如:
SELECT ... INTO TEMPORARY ...;
但是在導出時(約 30 分鐘)保持長時間交易是否明智?或者我可以在使用臨時表時省略事務以及如何?還是我只是用不必要的問題困擾自己,而最好的解決方案是將這些名稱儲存為正常表,僅在每次導出之前將其截斷以具有實際名稱?
- postgres 9.3.10
假設目前 Postgres 9.4。
由於您只處理約 20 個產品名稱,因此您如何向查詢提供這些名稱在很大程度上無關緊要。索引會浪費時間,Postgres 無論如何都會使用順序掃描(從您在問題中披露的內容來看)。
您可以使用在會話期間存在的臨時表,而不僅僅是您似乎假設的事務。你甚至可以在臨時表上創建索引,在這種情況下它只是無濟於事。
請務必
ANALYZE
手動在臨時表上執行:或者您也可以取消嵌套提供的數組文字。但是不要依賴在
SELECT
列表中並行取消嵌套兩個數組的過時技巧。這很容易出錯。將其移至 from 子句。我建議:SELECT ... LEFT JOIN unnest('{name1,name2,name3}'::text[]) WITH ORDINALITY product_names (name, type_id) USING (type_id) ...
更多的:
假設列名
type_id
在左側表中是明確的。如果您實際上沒有
type_id
像範例建議的那樣從 1 開始升序,請考慮unnest()
採用多個數組參數的新變體:SELECT ... LEFT JOIN unnest('{4,7,9}'::int[], '{name1,name2,name3}'::text[]) product_names (type_id, name) USING (type_id) ...
更多的: