Exadata 列裁剪(Column Projection)实现原理
一、概述
Exadata 的列裁剪并非在数据库服务器内存中“过滤”,而是通过 Smart Scan 的“函数下推(Function Shipping)”架构,将列的选择与提取工作完全下推到存储服务器(Cell)的 CPU 上执行。
存储服务器只将查询真正需要的列的数据返回给数据库服务器,从而在 物理 I/O 和 网络传输 两个层面实现裁剪。
二、实现基石:函数下推与 SQL 语句解析
当数据库服务器收到一条 SQL 时:
- 解析 SQL 并生成执行计划。
- 如果判定适合 Smart Scan(通常是全表扫描或快速全索引扫描),则不再将整个数据块发送给存储服务器。
- 将 SQL 操作“下推”,把与列裁剪相关的信息发送给存储服务器。
下推的“包裹”中包含两个关键指令:
- 谓词条件(WHERE):用于行过滤,告知存储服务器哪些行满足条件。
- 列列表(SELECT):即列投影的“蓝图”,明确告知存储服务器只需处理并返回哪些列。
存储服务器上的 CELLSRV 进程接收并执行这些指令,像一个小型数据库一样,在数据块上直接完成行筛选和列提取。
三、核心执行流程:存储服务器内部发生了什么
根据数据存储格式的不同,列裁剪会走上两条高效路径。
路径一:针对 HCC 压缩数据 —— 直接扫描,按需解压
如果表使用了 混合列压缩(HCC),数据在存储服务器上按列组织并压缩存储,为列裁剪提供了天然优势。
当 Smart Scan 处理 HCC 数据时:
- 不会先解压整个数据块,而是直接在压缩数据上操作。
- 根据下推的列列表,直接定位到所需列所在的压缩单元。
- 仅对目标列的数据进行按需解压。
- 在解压后的数据上应用谓词过滤,并提取结果。
官方文档明确指出:只有最终需要返回给客户端的列和行,才会在内存中被解压。
这意味着,如果一张表有 100 列,但查询只涉及 3 列,另外 97 列的压缩数据甚至不会被触及,极大节省了存储服务器的 CPU 和 I/O 资源。
路径二:针对列式闪存缓存 —— 纯列式格式加速
Exadata 的闪存缓存实现了双格式架构(Dual-Format Architecture):
- 当频繁扫描的 HCC 数据被加载到闪存缓存时,系统会自动将其转换为纯列式(Pure Columnar)格式存储。
- 当 Smart Scan 在闪存中扫描这种纯列式数据时,因为数据本身按列独立存储,读取指定列极其高效,完全避免了在行格式中定位列所需的额外开销。
- Smart Scan 只需读取查询中选定的列,大幅减少闪存 I/O 和存储服务器 CPU 使用量。
四、性能收益与关键限制
性能收益
列裁剪的收益巨大,典型例子:
- 一张表有 1 TB 数据,但查询结果只涉及少数列和行。
- 最终只需 2 MB 的数据从存储服务器传输到数据库服务器。
- 对于宽表(列数多)或包含 LOB 大对象的表,节省的 I/O 带宽尤其显著。
关键限制
- 对于非 HCC 压缩的表,Smart Scan 在一次扫描中最多只能投影 254 列。
- 如果查询选择的列数超过这个限制,部分列将无法被投影,需要将更多数据返回给数据库服务器处理,从而影响性能。
五、总结
Exadata 的列裁剪是一个深度软硬件协同的过程:
- 始于数据库服务器对 SQL 的解析和下推。
- 核心执行发生在存储服务器(Cell)的 CPU 上。
- 通过直接操作 HCC 压缩数据或纯列式闪存数据,存储服务器能够“精准地”只读取和返回查询所需的列。
- 将传统架构中“读取整行 → 网络传输 → 内存过滤”的模式,转变为“在存储层精准提取 → 只传输必需列”的高效模式。
这正是 Exadata 能够实现数量级性能提升的关键原因之一。
浙公网安备 33010602011771号