我有一个大表 作为此操作的一部分,从第一次插入返回的行id需要在第二次插入第二个表时使用.

我使用的CTE看起来像这样:

WITH inserted_data AS (
    INSERT INTO table1 (column1, column2, column3, column4)
    SELECT value1, value2, value3, value4
    FROM original_table
    RETURNING rowid, column4
)
INSERT INTO table2 (table1_id, column4)
SELECT rowid, column4
FROM inserted_data;

问题是,这太慢了,令人无法接受.对于仅4800行,它需要21秒,而对于9600行,它需要大约50秒.按照这个速度,我预计5000万张唱片需要3天左右的时间.我有大约两个小时的时间限制.

如果只执行第一次INSERT(不执行CTE),则查询速度要快100倍,分别是4800和9600行的200毫秒和500毫秒.我知道第二次插入的时间也可以忽略不计.按照这个速度,查询将在分配的时间内完成.

问题是,我如何重写查询才能以单个查询可以完成的速度执行.将所有数据从数据库转移到外部程序将是一个麻烦和容易出错的问题,并且需要额外的资源.如果我做一些事情,比如用循环编写函数,那么我不会一下子插入,而且我预计那里的性能也会很差.我不认为使用临时餐桌会有什么帮助,因为问题似乎仅仅是CTE的存在.

我试过这个:

INSERT INTO table2 (table1_id, column4)
SELECT rowid, column4
FROM (
    WITH inserted_data AS (
        INSERT INTO table1 (column1, column2, column3, column4)
        SELECT value1, value2, value3, value4
        FROM original_table
        RETURNING rowid, column4
    )
)

但这给了我:

syntax error at or near "INTO"

推荐答案

将插入内容分成两个语句如何?第二个insert可能是这样的:

INSERT INTO table2
       (table1_id, column4)
SELECT t1.rowid
,      ot.column4
FROM   original_table ot
JOIN   table1 t1 
ON     t1.column1 = ot.value1
       AND t1.column2 = ot.value2
       AND t1.column3 = ot.value3
       AND t1.column4 = ot.value4

对于original_table中的每一行,联接条件查找插入到table1中的行.

Sql相关问答推荐

SQL查询以创建手头的流动余额?

PostgreSQL:获取每家店铺收入最高的员工

判断Pyspark生成的SQL查询

出现5次后,将所有正斜杠替换为连字符

为什么在这种情况下我不能使用LAG函数?

对任何(数组)使用LIKE?

SQL SELECT MOST NEST TIMESTAMP BEAT ORDER

使用generate_series()时,LEFT联接缺少日期/间隔

如何用HeidiSQL在Firebird中设置超时?

SQL将三个表中的三列组合为一列

使用递归CTE在BigQuery中获取文件路径

其中使用表名作为;行值;记录?

存储过程太慢

当 ansible 变量未定义或为空时,跳过 sql.j2 模板中的 DELETE FROM 查询

返回给定日期后的第 4 个工作日(不包括公众假期)

计算组内多个日期间隔go 年的累计天数

每次计数器增加时通过运行总重置进行分组

如何在 JSONB 数组的每个对象中添加新的键值对- PostgreSQL

如何在sparksql查询中使用日期值?

在 AWS athena 的视图之上创建视图时,如何消除此错误:列别名列表有 1 个条目但t有 4 列可用?