SQL更新需要4天才能完成1000万条记录

时间:2019-03-28 06:55:23

标签: oracle plsql query-performance

我想更新一个数据库表,该表具有来自临时表的一千万条记录。 但是我的更新查询执行了4天以上。

1。)我已经为更新搜索条件创建了索引     tax_ledger_item_tab。在party_type,identity,company上创建的索引。     我的搜索条件是关于party_type,身份,公司,delivery_type_id     如以下给出的查询所示,这些列不是表中的键。

我相信我无法为索引添加delivery_type_id,因为它将 通过查询进行更新,如果我将其添加到索引中,性能将会最差。

2。)临时表identity_invoice_info_cfv也将返回70,000条记录     也。

到目前为止,我相信我的更新执行计划成本将约为70000 * 1000万条记录。

如何通过以下更新查询获得性能增强?我只想更新delivery_type_id,仅提取列。

DECLARE

CURSOR get_records IS
  SELECT i.COMPANY, i.IDENTITY, i.CF$_DELIVERY_TYPE
    FROM identity_invoice_info_cfv i
   WHERE i.PARTY_TYPE_DB = 'CUSTOMER';

BEGIN

  FOR rec_ IN get_records LOOP
  dbms_output.put_line  (sysdate ); 

    UPDATE tax_ledger_item_tab t
       SET t.delivery_type_id = rec_.CF$_DELIVERY_TYPE, t.fetched = 'TRUE'
     WHERE t.party_type = 'CUSTOMER'
       AND t.identity = rec_.IDENTITY
       AND t.company = rec_.COMPANY
       AND t.delivery_type_id IS NULL;

    COMMIT;  

  END LOOP;

 END;

2 个答案:

答案 0 :(得分:3)

使用MERGE语句:

Oracle设置

CREATE TABLE identity_invoice_info_cfv ( COMPANY, IDENTITY, CF$_DELIVERY_TYPE, PARTY_TYPE_DB ) AS
SELECT 'A', 123, 456, 'CUSTOMER' FROM DUAL;

CREATE TABLE tax_ledger_item_tab ( identity, company, party_type, delivery_type_id, fetched ) AS
SELECT 123, 'A', 'CUSTOMER', CAST( NULL AS NUMBER ), 'FALSE' FROM DUAL;

合并

MERGE INTO tax_ledger_item_tab t
USING identity_invoice_info_cfv i
ON (
    t.identity      = i.identity
AND t.company       = i.COMPANY
AND t.party_type    = 'CUSTOMER'
AND i.PARTY_TYPE_DB = 'CUSTOMER'
)
WHEN MATCHED THEN
  UPDATE
  SET delivery_type_id = i.CF$_DELIVERY_TYPE,
      fetched          = 'TRUE'
  WHERE t.delivery_type_id IS NULL;

查询

SELECT * FROM tax_ledger_item_tab;

输出

IDENTITY | COMPANY | PARTY_TYPE | DELIVERY_TYPE_ID | FETCHED
-------: | :------ | :--------- | ---------------: | :------
     123 | A       | CUSTOMER   |              456 | TRUE   

db <>提琴here

答案 1 :(得分:2)

我希望您也可以使用Merge语句实现此目的。下面是相同的代码。请从您的角度测试一些示例数据,然后继续。

  Merge into tax_ledger_item_tab t
  using identity_invoice_info_cfv i
      on (t.party_type ='CUSTOMER' and t.identity=i.IDENTITY 
         and t.company = i.COMPANY  and i.PARTY_TYPE_DB = 'CUSTOMER')
       when matched then
             update set  
              t.delivery_type_id=i.CF$_DELIVERY_TYPE,
              t.fetched = 'TRUE' 
            where t.delivery_type_id IS NULL;
        commit;