Postgresql

在 SELECT 查詢中加入外部數據

  • November 23, 2015

我有幾個(~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)
...

更多的:

引用自:https://dba.stackexchange.com/questions/121700