ITPub博客

首页 > 数据库 > 数据库开发技术 > 左右SQL执行计划妙招 ⑧ ——执行计划SQL写法差异改变【rowid 的影响】

左右SQL执行计划妙招 ⑧ ——执行计划SQL写法差异改变【rowid 的影响】

原创 数据库开发技术 作者:梁敬彬 时间:2025-06-07 09:58:40 0 删除 编辑

往期回顾:

左右SQL执行计划妙招 ①——子查询的应用范围

左右SQL执行计划妙招 ②——Hint无效原因

左右SQL执行计划妙招 ③ ——执行计划SQL写法差异改变【with子句】

左右SQL执行计划妙招 ④ ——执行计划SQL写法差异改变【insert all】

左右SQL执行计划妙招 ⑤ ——执行计划利用设计特性改变【并行度影响】

左右SQL执行计划妙招 ⑥ ——执行计划SQL写法差异改变【rownum分页】

左右SQL执行计划妙招 ⑦——执行计划SQL写法差异改变【rownum实体化】



在SQL性能优化过程中,SQL的写法细节常常对执行计划产生不可忽视的影响。合理利用Oracle数据库的特性,能够让同一业务实现方案下的SQL拥有更高的执行效率。本篇将聚焦于rowid的使用,通过两个实际对比例子,详细剖析不同SQL写法对执行计划的影响,为SQL优化实战提供借鉴。

环境准备

首先,构建测试环境并初始化数据:

drop table t purge;
create table t as select * from dba_objects;
update t set object_id = rownum;
commit;
create index idx_object_id on t(object_id);
set autotrace off;
select rowid from t where object_id=8;

此时,可以查到object_id=8的数据行对应的rowid,例如:

ROWID
-----
AAAaq2AALAAApOrAAH

SQL写法与执行计划对比

1. 普通条件更新(语句1)

update t set object_name='abc' where object_id=8;
执行计划:
-----------------------------------------------------------------------------------
Plan hash value: 3890322047
-----------------------------------------------------------------------------------
| Id  | Operation         | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT  |               |     1 |    79 |     2   (0)| 00:00:01 |
|   1 |  UPDATE           | T             |       |       |            |          |
|*  2 |   INDEX RANGE SCAN| IDX_OBJECT_ID |     1 |    79 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------
   - dynamic sampling used for this statement (level=2)


统计信息:

         30  recursive calls
          2  db block gets
         75  consistent gets
          0  physical reads
        448  redo size
        680  bytes sent via SQL*Net to client
        616  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed


该语句的执行计划中,Oracle选择通过idx_object_id索引进行INDEX RANGE SCAN,然后定位数据行并执行更新。

2. 使用rowid精确定位(语句2)

update t set object_name='abc'  where object_id=8 and t.rowid='AAAaq2AALAAApOrAAH';
执行计划:
------------------------------------------------------------------------------------
Plan hash value: 815416494
------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT            |      |     1 |    91 |     1   (0)| 00:00:01 |
|   1 |  UPDATE                     | T    |       |       |            |          |
|*  2 |   TABLE ACCESS BY USER ROWID| T    |     1 |    91 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------------------------------------------------
   2 - filter("OBJECT_ID"=8)
统计信息:
          0  recursive calls
          3  db block gets
          1  consistent gets
          0  physical reads
          0  redo size
        682  bytes sent via SQL*Net to client
        650  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed


在此语句中,加入了rowid作为查询条件。Oracle直接根据rowid访问对应数据行,执行计划变为TABLE ACCESS BY USER ROWID,这一方式被认为是直接、跳跃式访问表中某条记录的最快途径。

分析

从执行计划及统计信息对比可以看出:

在这里插入图片描述

语句1 先通过索引查找,再定位到表中的记录,适合object_id存在索引的场景。

语句2 由于rowid已明确,无须再借助索引,可以绕过索引查找的步骤,直接到达物理存储位置。Oracle明确选择TABLE ACCESS BY USER ROWID这一最快的单行定位方式,提升了访问效率。

实际应用中,在已知rowid的情况下,采用rowid作为定位依据,可以减少数据库的消耗,实现最短路径访问。在批量或高并发更新场景下,尤其能展现出rowid方式的优势。

使用注意事项

1. ROWID的时效性

 - DDL操作影响:表重建、分区操作会改变ROWID

 - 数据移动影响:行迁移、行链接可能导致ROWID变化

 - 时间窗口:ROWID应在短时间内使用,避免失效

 2. 业务逻辑考虑

 - 数据一致性:确保ROWID对应的行仍然满足业务条件

 - 并发控制:考虑其他会话可能的数据修改

 - 错误处理:处理ROWID无效的情况

 3. 性能权衡

 - 查询开销:获取ROWID本身也需要成本

 - 应用复杂度:增加了应用逻辑的复杂性

 - 适用范围:并非所有场景都适合使用ROWID

小结

在特定的业务场景下,语句1和语句2在逻辑上完全等价,但性能表现却截然不同。TABLE ACCESS BY USER ROWID是Oracle中最快的访问方式,它通过直接的物理定位避免了索引查找的开销,大幅减少了逻辑读和递归调用。

理解和掌握ROWID的使用技巧,能够在适当场景下显著提升SQL执行效率。然而,ROWID的使用需要谨慎考虑其时效性和业务适用性,在性能优化和代码复杂度之间找到合适的平衡点。

未完待续..

左右SQL执行计划妙招 ⑨ ——执行计划SQL写法差异改变【缓存结果影响】

公众号:收获不止数据库

微信:ljbyxl1213

系列回顾



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9091385/viewspace-3086445/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
历任中电福富研究院副理事长、中盾安信研究院副院长、宁德时代技术顾问等职务,受聘电信集团专家和国家十四五课题负责人,著有《收获,不止Oracle》《收获,不止SQL优化》等多本畅销数据库技术书籍。

注册时间:2024-02-06

  • 博文量
    162
  • 访问量
    198088