【发布时间】:2015-11-25 23:38:40
【问题描述】:
我有一个 SQL 更新查询,它使用我的测试数据运行,但没有完成(2 小时或更长时间)我的生产数据。
查询的目的
我有一个使用代码字符串而不是 ID 的 ADDRESSES 表。因此,例如 ADDRESSES.COUNTRY_CODE = "USA" 而不是 3152。为了参照完整性,我将这些代码字符串更改为代码 ID。
架构
地址(约 356,000 条记录)
- ADDR_ID (PK)
- COUNTRY_CODE (varchar)
- 地址行 1 (varchar)
- 等
COUNTRY_CODES
- CODE_ID (PK)
- CODE_STRING (varchar)
- 等。
步骤
首先,我创建一个临时表来存储具有适当代码 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 表有约 356,000 条记录。没有错误;它仍在运行。
问题
为什么这个更新查询没有完成?是不是效率非常低?我想我可以看到子查询可能是 N2 算法,但我对 SQL 缺乏经验。
【问题讨论】:
-
我认为更新查询会影响表中的每一行,因为它没有 where 子句。您是否尝试过运行 SQL Profiler 来查看实际传递给数据库的内容?
-
我明白你的意思,@SimonPrice,但是这个查询确实成功地完成了预期的结果,数据集要小得多。我不完全确定 update-set-subquery 是如何工作的(我几个月前写了这个查询),所以我将重新访问文档以刷新我的记忆。
-
尝试在 ADDR_ID 列的 ADDRESS_TEMP 中添加索引。
-
如果要完成一个小得多的数据集,那么您正在使用的数据集有多大?
标签: sql oracle performance subquery