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