利用SQL执行计划设计特性改变IoT表类型句的妙招(⑬)执行计划详解

梁敬彬梁敬弘兄弟出品

往期回顾
左右SQL执行计划妙招 ①——子查询的应用范围
左右SQL执行计划妙招 ②——Hint无效原因
左右SQL执行计划妙招 ③——执行计划SQL写法差异改变【with子句】
左右SQL执行计划妙招 ④——执行计划SQL写法差异改变【insert all】
左右SQL执行计划妙招 ⑤——执行计划利用设计特性改变【并行度影响】
左右SQL执行计划妙招 ⑥——执行计划SQL写法差异改变【rownum分页】
左右SQL执行计划妙招 ⑦——执行计划SQL写法差异改变【rownum实体化】
左右SQL执行计划妙招 ⑧——执行计划SQL写法差异改变【rowid 的影响】
左右SQL执行计划妙招 ⑨——执行计划SQL写法差异改变【缓存结果影响】
左右SQL执行计划妙招 ⑩——执行计划SQL写法差异改变【分区条件有无】
左右SQL执行计划妙招 ⑪——执行计划利用设计特性改变【分区设计影响】
左右SQL执行计划妙招 ⑫——执行计划利用设计特性改变【Cluster类型】

索引组织表(Index-Organized Table,IOT)是Oracle特有的表结构,通过将表数据直接存储在索引结构中,从根本上消除了回表操作。本文通过对比实验,展示IOT表在执行计划和性能方面的独特优势。

环境准备:构建对比测试环境

创建结构相同的普通表和IOT表进行性能对比:

set autotrace off

-- 创建普通堆表
create table heap_addresses (
    empno     number(10),
    addr_type varchar2(10),
    street    varchar2(10),
    city      varchar2(10),
    state     varchar2(2),
    zip       number,
    primary key (empno)
);

-- 创建索引组织表
create table iot_addresses (
    empno     number(10),
    addr_type varchar2(10),
    street    varchar2(10),
    city      varchar2(10),
    state     varchar2(2),
    zip       number,
    primary key (empno)
)
organization index;

-- 插入相同的测试数据
insert into heap_addresses
select object_id,'WORK','123street','washington','DC',20123
from all_objects;

insert into iot_addresses
select object_id,'WORK','123street','washington','DC',20123
from all_objects;

commit;

对比实验:回表操作的性能差异

语句1:普通表的主键查询

set linesize 1000
set autotrace traceonly
select * from heap_addresses where empno=22;

执行计划:

--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                |     1 |    50 |     1   (0)| 00:00:01 |
|   1 | TABLE ACCESS BY INDEX ROWID | HEAP_ADDRESSES |     1 |    50 |     1   (0)| 00:00:01 |
|*  2 | INDEX UNIQUE SCAN           | SYS_C0013751   |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

统计信息
--------------------------------------------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        659  bytes sent via SQL*Net to client
        405  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

语句2:IOT表的主键查询

select * from iot_addresses where empno=22;
执行计划:


----------------------------------------------------------------------------------------
| Id  | Operation         | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                    |     1 |    50 |     1   (0)| 00:00:01 |
|*  1 | INDEX UNIQUE SCAN | SYS_IOT_TOP_104441 |     1 |    50 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

统计信息
-----------------------------------------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        751  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

核心差异分析

执行计划对比

观察两个执行计划的关键差异:

IOT表的技术原理

  • 普通表访问路径: 索引扫描获取ROWID → 根据ROWID回表获取数据(两次IO)
  • IOT表访问路径: 直接在索引结构中获取完整数据(一次IO)
  • IOT表实现了"表即索引,索引即表"的设计理念,数据直接存储在B树索引的叶子节点中,从根本上消除了回表操作。

    应用场景与性能考虑

    适用场景

  • 主键访问频繁:大部分查询通过主键进行
  • 读多写少:查询操作远多于DML操作
  • 数据量适中:避免索引结构过于复杂
  • 性能特征

  • 优势: 减少IO次数、提高缓存效率、优化存储空间
  • 限制: DML操作相对较慢、非主键查询需要二级索引支持
  • 总结

    IOT表通过消除回表操作,在主键访问场景下能够显著提升查询性能。从本例可以看出,IOT表将逻辑读从3次减少到2次,在大数据量环境下这种优势更加明显。选择IOT表需要综合考虑业务查询模式和数据特征,在合适的场景下能够实现显著的性能优化效果。

    未完待续…
    左右SQL执行计划妙招 ⑭ ——执行计划利用设计特性改变【物化视图影响】

    系列回顾

    “大白话人工智能” 系列
    “数据库拍案惊奇” 系列
    “世事洞明皆学问” 系列

    作者:收获不止数据库

    物联沃分享整理
    物联沃-IOTWORD物联网 » 利用SQL执行计划设计特性改变IoT表类型句的妙招(⑬)执行计划详解

    发表回复