繁体   English   中英

使用子查询进行SQL更新花费的时间太长

[英]SQL update with sub-query takes too long to run

我有一个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条记录。 没有错误; 它仍在运行。

为什么此更新查询未完成? 它效率极低吗? 我想我可以看到子查询可能是一种N 2算法,但是我对SQL没有经验。

只是对Oracle Optimizer内部的一个猜测:'ADDRESS_TEMP'没有主键,也没有在addr_id上的索引。 因此,更新实际上采用了n ^ 2方法。 它基本上通过temp表扫描地址表中的每一行。

因此,建议:将addr_id设为临时表的主键。

如果这不能帮助我们提供Oracle优化程序生成的执行树。 这将使幕后实际发生的事情更加清晰。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM