在Postgres中翻转翻转数据表

时间:2011-09-23 13:49:33

标签: postgresql

我有一个包含数百万条记录的表,我正在运行查询并将结果插入另一个客户端将查询的表中。这个过程大约需要20秒。

如何运行此查询,构建此新表而不影响可能针对目标表运行查询的任何客户端?

例如。我正在跑步

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 DBA时,我记得他们创建临时表,然后在当前表中翻转这些表。这在Postgres中是否可行/实用?

3 个答案:

答案 0 :(得分:4)

这里你想要的是最小化锁定时间,当然,如果你在事务中包含一个查询(需要一段时间),它就不会起作用。

在这种情况下,我假设您实际上刷新了'target_table',其中包含运行脚本时“blah”对象的位置是正确的吗?

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

答案 1 :(得分:0)

ALTER TABLE ... RENAME TO ...

ALTER TABLE name
    RENAME TO new_name

也许您可以选择中间表,然后删除target_table并将中间表重命名为target_table

当您尝试重命名时,我不知道这将如何与可能针对target_table运行的任何查询进行交互。

答案 2 :(得分: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上,你可以加快速度。