2011-05-12 87 views
2

我有用戶輸入我需要在表中查詢的值列表。該列表可能非常大,並且在編譯時不知道長度。我不認爲使用WHERE ... IN (...),而是認爲使用臨時表並針對它執行連接會更有效率。我在另一個SO問題中讀到了這個建議(目前找不到它,但是當我這樣做時會編輯)。使用臨時表來替換WHERE IN子句

大意是這樣的:

CREATE TEMP TABLE my_temp_table (name varchar(160) NOT NULL PRIMARY KEY); 

INSERT INTO my_temp_table VALUES ('hello'); 
INSERT INTO my_temp_table VALUES ('world'); 
//... etc 

SELECT f.* FROM foo f INNER JOIN my_temp_table t ON f.name = t.name; 

DROP TABLE my_temp_table; 

如果我有兩個,這些在同一時間去,我會不會得到一個錯誤,如果線程2名試圖線程1後創建臨時表?

我應該隨機生成TEMP表的名稱嗎?或者,如果我在事務中包裝整個事件,命名衝突會消失嗎?

這是Postgresql 8.2。

謝謝!

回答

3

有沒有必要擔心衝突。

pg_temp模式是特定於會話的。如果在單獨的會話中有一個併發語句,它將使用不同的模式(即使您將它看作具有相同的名稱)。

兩點需要注意,但是:

  1. 創建臨時對象時,都會在系統目錄創建一個臨時架構和對象本身。如果頻繁使用,會導致混亂。

    因此,對於小套/頻繁使用,它通常是更好地堅持到inwith聲明(這兩者的Postgres科佩斯很好用)。通過使用不可變設置返回函數,「欺騙」計劃者使用您正在尋找的計劃也是偶爾有用的。

  2. 如果您決定實際使用臨時表格,通常最好在完成填充後對其進行索引和分析。除此之外,你只是寫了一條with聲明。

2

建議您使用與查詢insteed:http://www.postgresql.org/docs/9.0/interactive/queries-with.html

它還創建臨時表,當查詢/交易完成後,其被破壞了,所以我相信應該沒有併發衝突。

+0

啊我看到我忘了提及我使用8.2,它似乎沒有。但看起來像VALUES可能會有幫助:http://www.postgresql.org/docs/8.2/interactive/queries-values.html – Jonathan 2011-05-12 17:22:13