Sql 诚实和为什么原始更新如此缓慢。你有产品价值的索引吗?感谢你的努力,但这两个表之间没有匹配?product_val是根据lookup_键查找的,因此,由于有超过1400万行,每个product_val必然有数千个实例。谢谢。@pinksalmon可以随意调整
Sql 诚实和为什么原始更新如此缓慢。你有产品价值的索引吗?感谢你的努力,但这两个表之间没有匹配?product_val是根据lookup_键查找的,因此,由于有超过1400万行,每个product_val必然有数千个实例。谢谢。@pinksalmon可以随意调整,sql,oracle,Sql,Oracle,诚实和为什么原始更新如此缓慢。你有产品价值的索引吗?感谢你的努力,但这两个表之间没有匹配?product_val是根据lookup_键查找的,因此,由于有超过1400万行,每个product_val必然有数千个实例。谢谢。@pinksalmon可以随意调整示例设置。我遇到了最坏的情况。如果没有匹配,“不存在”必须扫描整个表并更新所有行。虽然在我的示例中我可以这样做,但我不能在实际表上这样做,因为我们不允许更改它们。我想我仍在努力理解为什么选择会如此之快,而更新需要永远。谢谢。@PinkSalmo
诚实和为什么原始更新如此缓慢。你有产品价值的索引吗?感谢你的努力,但这两个表之间没有匹配?product_val是根据lookup_键查找的,因此,由于有超过1400万行,每个product_val必然有数千个实例。谢谢。@pinksalmon可以随意调整示例设置。我遇到了最坏的情况。如果没有匹配,“不存在”必须扫描整个表并更新所有行。虽然在我的示例中我可以这样做,但我不能在实际表上这样做,因为我们不允许更改它们。我想我仍在努力理解为什么选择会如此之快,而更新需要永远。谢谢。@PinkSalmon,因为您实际上正在为要更新的每一行运行select命令。@PinkSalmon我不知道如果您不能进行更改,为什么您会在这里寻求帮助!我们只是不能换桌子。SQL是对查找表上数据的一次性更新,以释放值供重复使用。@BobC这将有助于(避免每个更新行有一个FTS),但嵌套循环中的34K索引访问仍然需要很长时间。
CREATE TABLE lookup
(
lookup_key NUMBER(10,0) PRIMARY KEY,
lookup_name VARCHAR2(30)
);
CREATE TABLE products
(
product_key NUMBER(10,0) PRIMARY KEY,
product_val NUMBER(10,0)
);
SELECT * FROM lookup
WHERE lookup_name <> 'Redundant'
AND NOT EXISTS (SELECT 1 FROM products
where product_val = lookup_key);
UPDATE lookup
SET lookup_name = 'Redundant'
WHERE lookup_name <> 'Redundant'
AND NOT EXISTS (SELECT 1 FROM products
WHERE product_val = lookup_key);
create table lookup2 as select * from lookup
UPDATE lookup2
SET lookup_name = 'Redundant'
WHERE lookup_name <> 'Redundant'
AND NOT EXISTS (SELECT 1 FROM products
WHERE product_val = lookup_key);
create table tmp as
SELECT lookup_key FROM lookup
WHERE lookup_name <> 'Redundant'
AND NOT EXISTS (SELECT 1 FROM products
where product_val = lookup_key);
merge into lookup l
using (select * from tmp) t
on (l.lookup_key = t.lookup_key)
when matched then update set lookup_name = 'Redundant'
WHERE lookup_name <> 'Redundant';
drop table tmp;
CREATE TABLE lookup
as select
rownum lookup_key, 'xxxxx'||rownum as lookup_name
from dual connect by level <= 34000;
CREATE TABLE products
as
with a as
(select rownum i
from dual connect by level <= 1450000),
b as
(select /*+ MATERIALIZE */ rownum j
from dual connect by level <= 10)
select
i*10 + j + 34000 product_key, i*10 + j + 34000 as product_val
from a cross join b;
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 32957 | 1609K| 554 (3)| 00:00:10 |
|* 1 | HASH JOIN ANTI | | 32957 | 1609K| 554 (3)| 00:00:10 |
|* 2 | TABLE ACCESS FULL| LOOKUP | 32957 | 1190K| 19 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| PRODUCTS | 1320K| 16M| 530 (2)| 00:00:10 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("PRODUCT_VAL"="LOOKUP_KEY")
2 - filter("LOOKUP_NAME"<>'Redundant')
SQL> UPDATE lookup
2 SET lookup_name = 'Redundant'
3 WHERE lookup_name <> 'Redundant'
4 AND NOT EXISTS (SELECT 1 FROM products
5 WHERE product_val = lookup_key);
34000 rows updated.
Elapsed: 00:00:04.97
create index products_idx on products(PRODUCT_VAL);
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | 32 | 13 (0)| 00:00:01 |
| 1 | UPDATE | LOOKUP | | | | |
| 2 | NESTED LOOPS ANTI | | 1 | 32 | 13 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| LOOKUP | 1 | 19 | 11 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | PRODUCTS_IDX | 14M| 178M| 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("LOOKUP_NAME"<>'Redundant')
4 - access("PRODUCT_VAL"="LOOKUP_KEY")
SQL> UPDATE lookup
2 SET lookup_name = 'Redundant'
3 WHERE lookup_name <> 'Redundant'
4 AND NOT EXISTS (SELECT 1 FROM products
5 WHERE product_val = lookup_key);
1 row updated.
Elapsed: 00:00:00.13