2014-02-11 132 views
1

我需要創建臨時表,然後在選擇查詢中使用該臨時表。當我將這些語句放入函數中時,運行第二個語句需要很長時間。就像這樣:CREATE TABLE AS後SELECT需要很長時間才能運行

BEGIN 
    CREATE TABLE temp AS SELECT…. 
    INSERT INTO target_table SELECT * FROM tableA join temp… 
END; 

我意識到,當我與運行之間約60秒單獨運行。其中,第二條語句需要約2秒運行。如果我等了45秒,則需要很長時間才能運行。例如,如果我執行以下語句逐個(而不是在一個函數):

CREATE TABLE temp AS SELECT…. 

SELECT pg_sleep(60); 

INSERT INTO target_table SELECT * FROM tableA join temp… 

這需要很短的時間來執行的插入的一個。但是當我突出顯示他們並將它們一起運行時,需要永久執行。

我試圖把它們放在不同的BEGIN/END塊中的一個函數中。像這樣

BEGIN 
    CREATE TABLE temp AS SELECT…. 
    SELECT pg_sleep(120); 
END; 

BEGIN 
    INSERT INTO target_table SELECT * FROM tableA join temp… 
END; 

仍然沒有工作。

爲什麼要在兩者之間等待?爲什麼他們在工作時不工作?有沒有解決這個問題的方法?

回答

0

這不是問題的直接答案,但是如果問題是你覺得你需要一個像這樣的臨時表(這很少需要),那麼我會按照以下順序嘗試以下三種選擇之一:

  1. 使用子查詢而不是臨時表。優化器非常擅長處理複雜的SQL。
  2. 使用公共表格表達式(WITH子句):如果結果集非常大,那麼數據將實現爲臨時段,如果不是,則可以將其視爲子查詢。
  3. 使用全局臨時表。您不必立即使用執行,並且可以對錶格進行索引或收集表格(由於優化器動態取樣,很少需要)。

要診斷您的實際問題,我會考慮通過跟蹤或使用AWR來監視會話。

+0

我確實使用了子查詢。出於某種原因,子查詢也花了很長時間才能運行。臨時表的速度要快得多。我還使用了CREATE TABLE temp DROP ON COMMIT,並且這種方式也不起作用。 – toanong

+0

那語法是完全無效的。 「在提交刪除行時創建全局臨時表(col1,col2 ...)」。我認爲在移動到臨時表之前,您應該做得更好,以嘗試和診斷運行緩慢的子查詢的原因,可能會將其重寫爲公用表表達式。 –

2

我強烈懷疑這個問題是由於該表沒有統計信息而導致計劃選擇。請嘗試:

CREATE TABLE temp AS SELECT…. 
ANALYZE; 
INSERT INTO target_table SELECT * FROM tableA join temp… 

P. +1使用真正的橢圓。

相關問題