【发布时间】:2013-10-31 09:27:24
【问题描述】:
我的 oracle 数据库中的更新语句出现问题。 查询需要很长时间,并且临时表空间空间不足,但它提供了正确的数据。
我试图将子查询转换为联接,但我不知道如何正确地做到这一点。 如果有人知道如何改进语句或如何将其转换为联接,我将不胜感激。
UPDATE table1 t1
SET t1.inxdc = (SELECT sda_x
FROM table2 t2
WHERE t1.c1 = t2.c1
AND t1.c2 = t2.c2
AND t1.c3 = t2.c3
AND t1.c4 = t2.c4
AND t1.c5 = t2.c5
AND t1.c6 = t2.c6
AND t2.ident = 'K_SDA_W'
AND rownum=1)
WHERE EXISTS
(SELECT 1
FROM table2 t2
WHERE t1.c1 = t2.c1
AND t1.c2 = t2.c2
AND t1.c3 = t2.c3
AND t1.c4 = t2.c4
AND t1.c5 = t2.c5
AND t1.c6 = t2.c6
AND t2.ident = 'K_SDA_W');
编辑1: 表格的一些信息
- table1 PK = c1,c2,c3,c4,c5,c6
- table2 PKs = ident,c4,c5,c6,以及声明中未提及的其他 3 个 (c7,c8,c9)
- 索引:除了 PK 仅在 table2 c1 上
- table1 数据:12466 行
- table2 数据:194827 行
编辑2: 执行计划
--------------------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------------------
| 0 | UPDATE STATEMENT | |
| 1 | UPDATE | table1 |
| 2 | NESTED LOOPS SEMI | |
| 3 | TABLE ACCESS FULL | table1 |
| 4 | TABLE ACCESS BY INDEX ROWID| table2 |
| 5 | INDEX RANGE SCAN | t2.c1 |
| 6 | COUNT STOPKEY | |
| 7 | TABLE ACCESS BY INDEX ROWID| table2 |
| 8 | INDEX RANGE SCAN | t2.PK |
--------------------------------------------------------------
【问题讨论】:
-
T1 和 T2 哪个更大? T1和T2的PK是多少?有索引吗?
-
您的表有多大,运行此更新需要多长时间?你能告诉我们执行计划吗?子查询是否使用一些索引?从
table1中的一个相关行的子查询中检索一个值需要多长时间? -
为什么 rownum = 1? T2中是否有重复项?这是否意味着 T2 > T1 的大小?计划在说什么!
标签: oracle join sql-update exists database-performance