2011-09-23 31 views
0

我有一個包含數百萬條記錄的表,我正在運行查詢並將結果插入另一個表中,客戶將查詢。這個過程大約需要20秒。Postgres中的Flip Flipping數據表

如何運行此查詢,構建此新表而不影響可能正在對目標表運行查詢的任何客戶端?

例如,我跑

BEGIN; 
DROP TABLE target_table; 
SELECT blah, blahX, blahY 
INTO target_table 
FROM source_table 
GROUP BY blahX, blahY 
COMMIT; 

然後阻止查詢:

SELECT SUM(blah) 
FROM target_table 
WHERE blahX > x 

在有工作的日子,一些SQL Server數據庫管理員的我記得他們創建臨時表,然後在當前的翻轉這些表。這在Postgres中可行嗎?

回答

4

這裏你想要的是儘量減少鎖定時間,當然如果你在事務中包含一個查詢(這需要一段時間)是不行的。

在這種情況下,我認爲當你運行你的腳本時,你實際上正在刷新包含「blah」對象位置的'target_table'是否正確?

BEGIN; 
CREATE TEMP TABLE temptable AS 
SELECT blah, blahX, blahY 
FROM source_table 
GROUP BY blahX, blahY 
COMMIT; 

BEGIN; 
TRUNCATE TABLE target_table 
INSERT INTO target_table(blah,blahX,blahY) 
    SELECT blah,blahX,blahY FROM temptable; 
DROP TABLE temptable; 
COMMIT; 

正如在評論中提到的,它會更快截斷之前刪除索引的,只是加載數據,以避免不需要的指標的變化之後重新創建它們。

爲了什麼,是不可能在PostgreSQL在這方面的全部細節: http://postgresql.1045698.n5.nabble.com/ALTER-TABLE-REPLACE-WITH-td3305036i40.html

+0

出於興趣,如果另一個會話在您嘗試刪除時針對'target_table'運行查詢,將另一個表重命名爲'target_table'並執行COMMIT,會發生什麼? – NPE

+0

交易受益於隔離,所以通常會出現「表可用,查詢正常」,「交易開始,表鎖定,無查詢」,「交易完成,查詢正常」。至少它應該這樣工作......我認爲表格鎖定在target_table上是隱含的。唯一的問題是「查詢是否等待表可以查看新的target_table作爲他們試圖查詢的表?」。老實說,我沒有線索,如果我不希望引擎處理它,我肯定會更喜歡刪除/插入解決方案;) –

+0

(+1)非常好,謝謝你。 – NPE

0

ALTER TABLE ... RENAME TO ...

ALTER TABLE name 
    RENAME TO new_name 

也許你可以選擇到一箇中間表,然後刪除target_table和中間表重命名爲target_table

我不知道這將如何與您嘗試執行重命名時可能針對target_table運行的任何查詢進行交互。

+0

那麼,如何PG TEMP和燙髮表區分? –

+0

@Neil Middleton:請注意,我的建議沒有涉及臨時表。 – NPE

+0

@NeilMiddleton:TEMP TABLES是這樣創建的:CREATE TEMP TABLE ..。請注意,我的答案使用臨時表,這是去恕我直言的方式。 –

0

您可以創建一個表,刪除一個表,然後在我曾經使用的每個SQL版本中重命名錶。

BEGIN; 
SELECT blah, blahX, blahY 
INTO new_table 
FROM source_table 
GROUP BY blahX, blahY; 
DROP TABLE target_table; 
ALTER TABLE new_table RENAME TO target_table; 
COMMIT; 

我不確定我的頭頂是否可以在PostgreSQL中使用臨時表。 PostgreSQL在特殊模式下創建臨時表;你不會選擇模式。但是您可以將其作爲臨時表創建,刪除現有表並將其與SET SCHEMA一起移動。

在某些時候,任何這些都需要一個表鎖。 (Duh。)通過將可交換表放置在SSD上,您可能可以加快速度。