sql – IN子句如何影响oracle的性能?

UPDATE table1 
       SET col1 = 'Y'
     WHERE col2 in (select col2 from table2)

在上面的查询中,假设内部查询返回10000行.带有IN子句的查询是否会影响性能

如果是这样,可以做些什么来加快执行速度?

解决方法

如果子查询与TABLE1中的行数相比返回大量行,则优化器可能会生成如下计划:
--------------------------------------------------------------------------------
| Id  | Operation           | Name   | Rows  | Bytes |TempSpc| Cost (%cpu)| Time
--------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT    |        |   300K|    24M|       |  1581   (1)| 00:0
|   1 |  UPDATE             | TABLE1 |       |       |       |            |
|*  2 |   HASH JOIN SEMI    |        |   300K|    24M|  9384K|  1581   (1)| 00:0
|   3 |    TABLE ACCESS FULL| TABLE1 |   300K|  5860K|       |   355   (2)| 00:0
|   4 |    TABLE ACCESS FULL| TABLE2 |   168K|    10M|       |   144   (2)| 00:0
--------------------------------------------------------------------------------
Predicate information (identified by operation id):
---------------------------------------------------
   2 - access("COL2"="COL2")

它将扫描两个表并仅更新两个表共有的TABLE1中的行.如果您需要更新大量行,这是一个高效的计划.

有时,与TABLE1中的行数相比,内部查询将具有很少的行.如果TABLE1(col2)上有索引,则可以获得与此类似的计划:

-------------------------------------------------------------------------------
| Id  | Operation            | Name   | Rows  | Bytes | Cost (%cpu)| Time     |
-------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT     |        |    93 |  4557 |   247   (1)| 00:00:03 |
|   1 |  UPDATE              | TABLE1 |       |       |            |          |
|   2 |   nesTED LOOPS       |        |    93 |  4557 |   247   (1)| 00:00:03 |
|   3 |    SORT UNIQUE       |        |    51 |  1326 |   142   (0)| 00:00:02 |
|   4 |     TABLE ACCESS FULL| TABLE2 |    51 |  1326 |   142   (0)| 00:00:02 |
|*  5 |    INDEX RANGE SCAN  | IDX1   |     2 |    46 |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate information (identified by operation id):
---------------------------------------------------
   5 - access("T1"."COL2"="T2"."COL2")

在这种情况下,Oracle将读取TABLE2中的行,并为每个(唯一)行执行对TABLE1的索引访问.

哪个访问更快取决于内部查询的选择性和TABLE1上索引的聚类(TABLE1中col2值相似的行是彼此相邻还是随机扩展?).在任何情况下,性能方面,如果您需要执行此更新,此查询是最快的方法之一.

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...