Sql 更新 1000 万条记录需要 4 天
Sql update takes 4 days for 10 million records
我想更新一个数据库 table,它有超过 1000 万条来自临时 table 的记录。
但是我的更新查询执行了超过 4 天。
1.) 我已经为更新搜索条件创建了一个索引
tax_ledger_item_tab。索引创建于 party_type、身份、公司。
我的搜索条件是 party_type、身份、公司、delivery_type_id
如以下给定查询,这些列不是 table.
中的键
我相信我不能为索引添加 delivery_type_id 因为它会
通过查询更新,如果我将其添加到索引中,性能将最差。
2.) 临时 table identity_invoice_info_cfv 也将 returns 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;
我希望您也可以使用 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;
使用 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<>fiddle here
我想更新一个数据库 table,它有超过 1000 万条来自临时 table 的记录。 但是我的更新查询执行了超过 4 天。
1.) 我已经为更新搜索条件创建了一个索引 tax_ledger_item_tab。索引创建于 party_type、身份、公司。 我的搜索条件是 party_type、身份、公司、delivery_type_id 如以下给定查询,这些列不是 table.
中的键我相信我不能为索引添加 delivery_type_id 因为它会 通过查询更新,如果我将其添加到索引中,性能将最差。
2.) 临时 table identity_invoice_info_cfv 也将 returns 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;
我希望您也可以使用 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;
使用 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<>fiddle here