确认smart scan是否真正生效需查v$sql中io_cell_offload_eligible_bytes与io_interconnect_bytes比值是否>90%,并结合v$cell_io_recursive_advise中advise_type='smart_scan'记录验证谓词下推等子特性,而非仅依赖执行计划中的full扫描。

直接看 V$SQL 和 V$CELL_IO_RECURSIVE_ADVISE,别只盯着执行计划里有没有 “FULL” —— 那只是必要条件,不是充分条件。
怎么确认 Smart Scan 真正在工作
执行计划出现 TABLE ACCESS FULL 或 INDEX FAST FULL SCAN,不代表 Smart Scan 就生效了。真正生效的证据在运行时指标里:
-
V$SQL中查目标 SQL 的IO_CELL_OFFLOAD_ELIGIBLE_BYTES和IO_INTERCONNECT_BYTES:前者是“本可卸载的数据量”,后者是“实际从存储节点传过来的字节数”。如果两者接近(比如比值 > 90%),说明 Smart Scan 过滤很高效;如果IO_INTERCONNECT_BYTES接近IO_CELL_OFFLOAD_ELIGIBLE_BYTES,那基本等于没过滤,全量传输了。 -
V$CELL_IO_RECURSIVE_ADVISE(Exadata 19c+)能告诉你某次扫描是否触发了谓词下推、列投影、布隆过滤等具体子特性。查ADVISE_TYPE= 'SMART_SCAN' 的记录,再结合SQL_ID关联确认。 - 避免误判:
cell smart table scan等待事件出现 ≠ Smart Scan 高效。它只表示存储节点参与了扫描,但可能因谓词无法下推(比如用了TO_DATE(col, '...'))、数据格式不支持(非 ORACLE_DATAPUMP 格式外部表)、或文件不在 Exadata 存储上,导致过滤失效。
哪些操作会让 Smart Scan “失效但不报错”
Smart Scan 不会报错退出,而是静默退化为传统读取 —— 数据全量拉到 DB 节点再过滤,性能断崖下跌。常见诱因有:
- 外部表用了不支持的访问驱动:只有
ORACLE_LOADER(文本)和ORACLE_DATAPUMP(二进制 dump)能触发 Smart Scan;ORACLE_HDFS或自定义驱动通常不行,除非配置了 Exadata 兼容模式且 HDFS 位于 Cell 上。 - WHERE 条件含不可下推函数:比如
UPPER(col) = 'X'、SUBSTR(col,1,3) = 'ABC'、TO_CHAR(date_col)。Cell Server 只支持有限函数集(如=、、BETWEEN、LIKE(无前导通配符)、部分正则REGEXP_LIKE)。 - 时区升级状态异常:查
SELECT property_value FROM database_properties WHERE property_name='DST_UPGRADE_STATE',结果不是NONE会全局禁用 Smart Scan。 - 隐式类型转换:比如查询字段是
VARCHAR2,但 WHERE 里写col = 123(数字),触发隐式转换后谓词无法下推。
外部表场景下 Smart Scan 效率低的典型表现
外部表(尤其是 CSV/Text)是 Smart Scan 最易“看似启用实则无效”的场景:
- 字段分隔符含转义字符或嵌套引号(如
"a,b","c""d"),导致 Cell Server 无法安全解析行结构,自动放弃行过滤。 - 未指定
REJECT LIMIT UNLIMITED且文件存在格式错误行:Cell Server 遇到解析失败会中止 Smart Scan,回退到 DB 节点逐行解析。 - 列投影失效:SELECT 列表里写了
*或大量冗余列,即使 WHERE 过滤高效,传输量仍巨大。务必显式列出所需列。 - 文件未按 Cell Server 偏好格式存放:比如放在 ASM diskgroup 但底层存储不是 Exadata Cell(例如混用了普通 NAS),
cell_offload_processing参数虽为 TRUE,但物理路径不满足前提。
诊断时最容易被忽略的点
很多人查完 V$SQL 就停了,但关键细节藏在更底层:
-
V$CELL_STATE和V$CELL_CONFIG必须核对:确认所有 Cell 处于online状态,且cell_offload_processing在所有 Cell 上都为ENABLED(不只是数据库参数)。 - 单次 SQL 执行可能混合多种 I/O 模式:比如大表扫描走了 Smart Scan,但连接的小表走的是 buffer cache 访问 —— 此时
V$SQL的汇总指标会掩盖局部失效,得用DBMS_MONITOR.SESSION_TRACE_ENABLE+tkprof看每个对象的实际等待事件和 bytes 传输量。 - 并行度影响:串行查询可能因
_serial_direct_read设置或对象大小未达阈值(_small_table_threshold),跳过直接路径读,从而绕过 Smart Scan 触发链。











