SQL 使用子查询更新花费的时间太长 运行
SQL update with sub-query takes too long to run
我有一个 SQL 更新查询与我的测试数据一起运行,但没有完成(2 小时或更长时间)与我的生产数据。
查询目的
我有一个使用代码字符串而不是 ID 的地址 table。因此,例如 ADDRESSES.COUNTRY_CODE = "USA" 而不是 3152。为了参照完整性,我将这些代码字符串更改为代码 ID。
架构
地址(~356,000 条记录)
- ADDR_ID(PK)
- COUNTRY_CODE (varchar)
- 地址行 1 (varchar)
- 等等
COUNTRY_CODES
- CODE_ID(PK)
- CODE_STRING (varchar)
- 等
步骤
首先,我创建一个临时 table 来存储具有适当代码 ID 的地址记录:
CREATE TABLE ADDRESS_TEMP
AS
SELECT ADDR_ID, CODE_ID
FROM ADDRESSES
LEFT JOIN
COUNTRY_CODES
ON ADDRESSES.COUNTRY_CODE = CODE_STRING
其次,我将 COUNTRY_CODE 列清空并将其类型更改为 NUMBER。
第三,我将 COUNTRY_CODE 列设置为代码 ID:
UPDATE ADDRESSES
SET COUNTRY_CODE =
(SELECT ADDRESS_TEMP.CODE_ID
FROM ADDRESS_TEMP
WHERE ADDRESS_TEMP.ADDR_ID = ADDRESSES.ADDR_ID)
这第三步需要几个小时才能完成(2 小时并且还在增加)。 ADDRESSES table 有大约 356,000 条记录。没有错误;仍然是 运行.
问题
为什么这个更新查询没有完成?它效率低下吗?我想我可以看到子查询如何成为 N2 算法,但我对 SQL.
没有经验
只是对 Oracle 优化器内部结构的猜测:'ADDRESS_TEMP' 在 addr_id 上没有主键或任何索引。因此,更新确实采用了 n^2 方法。它基本上通过临时 table 扫描地址 table 中的每一行。
因此,建议:使 addr_id 成为临时 table 的主键。
如果这不能帮助我们提供 Oracle 优化器生成的执行树。这将使幕后实际发生的事情更加清晰。
我有一个 SQL 更新查询与我的测试数据一起运行,但没有完成(2 小时或更长时间)与我的生产数据。
查询目的
我有一个使用代码字符串而不是 ID 的地址 table。因此,例如 ADDRESSES.COUNTRY_CODE = "USA" 而不是 3152。为了参照完整性,我将这些代码字符串更改为代码 ID。
架构
地址(~356,000 条记录)
- ADDR_ID(PK)
- COUNTRY_CODE (varchar)
- 地址行 1 (varchar)
- 等等
COUNTRY_CODES
- CODE_ID(PK)
- CODE_STRING (varchar)
- 等
步骤
首先,我创建一个临时 table 来存储具有适当代码 ID 的地址记录:
CREATE TABLE ADDRESS_TEMP
AS
SELECT ADDR_ID, CODE_ID
FROM ADDRESSES
LEFT JOIN
COUNTRY_CODES
ON ADDRESSES.COUNTRY_CODE = CODE_STRING
其次,我将 COUNTRY_CODE 列清空并将其类型更改为 NUMBER。
第三,我将 COUNTRY_CODE 列设置为代码 ID:
UPDATE ADDRESSES
SET COUNTRY_CODE =
(SELECT ADDRESS_TEMP.CODE_ID
FROM ADDRESS_TEMP
WHERE ADDRESS_TEMP.ADDR_ID = ADDRESSES.ADDR_ID)
这第三步需要几个小时才能完成(2 小时并且还在增加)。 ADDRESSES table 有大约 356,000 条记录。没有错误;仍然是 运行.
问题
为什么这个更新查询没有完成?它效率低下吗?我想我可以看到子查询如何成为 N2 算法,但我对 SQL.
没有经验只是对 Oracle 优化器内部结构的猜测:'ADDRESS_TEMP' 在 addr_id 上没有主键或任何索引。因此,更新确实采用了 n^2 方法。它基本上通过临时 table 扫描地址 table 中的每一行。
因此,建议:使 addr_id 成为临时 table 的主键。
如果这不能帮助我们提供 Oracle 优化器生成的执行树。这将使幕后实际发生的事情更加清晰。