当前位置: 首页 > ops >正文

Oracle 执行计划中的 ACCESS 和 FILTER 详解

Oracle 执行计划中的 ACCESS 和 FILTER 详解

在 Oracle 执行计划中,ACCESSFILTER 是两个关键的操作类型,它们描述了 Oracle 如何检索和处理数据。理解这两个概念对于 SQL 性能调优至关重要。

ACCESS(访问)

ACCESS 表示 Oracle 通过索引或直接访问表的方式来获取数据。

特点

  1. 索引访问:通常通过索引快速定位数据
  2. 高效检索:直接访问所需数据块,减少I/O
  3. 访问路径:包括索引唯一扫描(INDEX UNIQUE SCAN)、索引范围扫描(INDEX RANGE SCAN)等

常见 ACCESS 操作类型

操作类型描述示例
INDEX UNIQUE SCAN通过唯一索引查找单行主键查找
INDEX RANGE SCAN通过索引查找多行WHERE id BETWEEN 100 AND 200
INDEX FULL SCAN全索引扫描需要索引列但无过滤条件
INDEX FAST FULL SCAN快速全索引扫描类似全表扫描但只读索引
TABLE ACCESS FULL全表扫描无合适索引时
TABLE ACCESS BY INDEX ROWID通过索引ROWID访问表索引覆盖不全时

ACCESS 示例

-- 索引唯一扫描示例
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE employee_id = 100;-- 执行计划中会出现:
-- | Id | Operation                   | Name          |
-- |----|-----------------------------|---------------|
-- |  0 | SELECT STATEMENT            |               |
-- |  1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES     |
-- |  2 |   INDEX UNIQUE SCAN         | EMP_ID_PK     |

FILTER(过滤)

FILTER 表示 Oracle 对已获取的数据应用额外的过滤条件。

特点

  1. 后置过滤:在获取数据后应用条件
  2. 性能影响:可能导致处理更多数据
  3. 常见场景:无法使用索引的条件、函数条件等

常见 FILTER 操作场景

  1. 对索引列应用函数:

    WHERE UPPER(last_name) = 'SMITH'
    
  2. 使用不等于(!=或<>)操作:

    WHERE department_id != 10
    
  3. 使用OR条件:

    WHERE department_id = 10 OR salary > 5000
    
  4. 使用LIKE以通配符开头:

    WHERE last_name LIKE '%SMITH%'
    

FILTER 示例

-- 过滤条件示例
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE salary > 5000 AND UPPER(last_name) = 'SMITH';-- 执行计划中可能出现:
-- | Id | Operation         | Name      |
-- |----|-------------------|-----------|
-- |  0 | SELECT STATEMENT  |           |
-- |* 1 |  TABLE ACCESS FULL| EMPLOYEES |
--
-- Predicate Information:
-- 1 - filter("SALARY">5000 AND UPPER("LAST_NAME")='SMITH')

ACCESS 与 FILTER 对比

特性ACCESSFILTER
执行时机数据获取阶段数据获取后
效率通常高效可能低效
索引使用通常使用索引通常不使用索引
优化目标尽可能多使用尽可能减少
典型操作索引扫描条件过滤

性能优化建议

  1. 将FILTER转为ACCESS

    • 为常用查询条件创建合适索引
    • 重写SQL避免对索引列使用函数
  2. 复合索引策略

    -- 创建复合索引支持多列查询
    CREATE INDEX emp_name_salary_idx ON employees(last_name, salary);
    
  3. 避免全表扫描

    • 确保查询能使用索引
    • 使用INDEX提示强制使用索引
  4. 函数索引

    -- 为函数条件创建函数索引
    CREATE INDEX emp_upper_name_idx ON employees(UPPER(last_name));
    
  5. 统计信息更新

    -- 确保统计信息准确
    EXEC DBMS_STATS.GATHER_TABLE_STATS('HR', 'EMPLOYEES');
    

实际案例分析

案例1:将FILTER转为ACCESS

问题SQL

SELECT * FROM orders WHERE TO_CHAR(order_date, 'YYYY-MM') = '2023-01';

执行计划

TABLE ACCESS FULL ORDERSFILTER: TO_CHAR(order_date, 'YYYY-MM') = '2023-01'

优化方案

-- 方案1: 使用范围查询
SELECT * FROM orders 
WHERE order_date >= TO_DATE('2023-01-01', 'YYYY-MM-DD')
AND order_date < TO_DATE('2023-02-01', 'YYYY-MM-DD');-- 方案2: 创建函数索引
CREATE INDEX orders_ym_idx ON orders(TO_CHAR(order_date, 'YYYY-MM'));

案例2:复合索引优化

问题SQL

SELECT * FROM employees 
WHERE department_id = 10 
AND salary > 5000;

执行计划

TABLE ACCESS FULL EMPLOYEESFILTER: department_id = 10 AND salary > 5000

优化方案

-- 创建复合索引
CREATE INDEX emp_dept_sal_idx ON employees(department_id, salary);

优化后执行计划将显示使用索引范围扫描(INDEX RANGE SCAN)。

总结

  1. ACCESS 表示数据检索方式,FILTER 表示数据获取后的过滤
  2. 优化目标是将尽可能多的 FILTER 条件转为 ACCESS 条件
  3. 通过创建合适索引、重写SQL语句可以减少FILTER操作
  4. 使用执行计划工具定期检查SQL性能,识别不必要的FILTER操作
http://www.xdnf.cn/news/4875.html

相关文章:

  • 数据可视化大屏——物流大数据服务平台(二)
  • 从生产事故看软件质量保障:开发规范落实与时间资源矛盾的深度探讨
  • 如何清除windows 远程桌面连接的IP记录
  • kafka 面试总结
  • 仁合医疗核心产品:引领医疗科技新潮流
  • 从 Git 到 GitHub - 使用 Git 进行版本控制 - Git 常用命令
  • 数据同步选择推Push还是拉Pull
  • 45.传导发射整改摸底测试方法
  • 文旅田园康养小镇规划设计方案PPT(85页)
  • C++23 views::chunk_by (P2443R1) 详解
  • 信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(十三)(1)
  • 3D桌面可视化开发平台HOOPS Native Platform,如何实现3D系统快速开发与部署?
  • stm32 debug卡在0x1FFFxxxx
  • OPC UA 介绍及开发示例
  • 【Survival Analysis】【机器学习】【3】deepseek流程图
  • 22、城堡防御工事——React 19 错误边界与监控
  • 如何用Jmeter实现自动化测试?
  • 【MySQL】存储引擎 - FEDERATED详解
  • WPF之静态资源与动态资源
  • 从 AGI 到具身智能体:解构 AI 核心概念与演化路径全景20250509
  • JVM详解
  • 路由组件1
  • 创建没有 TPM 和安全启动的 Windows 11 可启动 USB 驱动器
  • 【MySQL】数据库、数据表的基本操作
  • SIGIR 2025端到端生成式推荐ETEGRec
  • 详解:ai证书有哪些?
  • MCP开发入门
  • C++ stl中的stack和queue的相关函数用法
  • uniapp 百家云直播插件打包失败
  • 在ISOLAR A/B 工具使用UDS 0x14服务清除单个DTC故障的配置