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

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操作

相关文章:

  • 【软件设计师:体系结构】15.计算机体系结构概论
  • PIC18F45K80 ECAN模块使用
  • 第J7周:对于ResNeXt-50算法的思考
  • Java学习手册:微服务设计原则
  • Dify之八添加各种在线大模型
  • 为特定领域微调嵌入模型:打造专属的自然语言处理利器
  • 学习黑客5 分钟读懂什么是 CVE?
  • html object标签介绍(用于嵌入外部资源通用标签)(已不推荐使用deprecated,建议使用img、video、audio标签)
  • 前端使用腾讯地图api实现定位功能
  • 损失函数(平方损失MSE、绝对值损失MAE、负对数似然损失NLL、交叉熵损失CEL和二元交叉熵损失BCE)原理、公式调库实现与手动实现
  • IC解析之TPS92682-Q1(汽车LED灯控制IC)
  • Dp通用套路(闫式)
  • 39-算法打卡-二叉树-基础知识-第三十九天
  • 从零开始的python学习(六)P86+P87+P88
  • 有关SOA和SpringCloud的区别
  • MySQL 8.0 OCP 英文题库解析(二)
  • C++ stl中的stack和queue的相关函数用法
  • 23盘古石决赛
  • 前端自学入门:HTML 基础详解与学习路线指引
  • 安装jdk步骤
  • 做商城网站需要准备那些/国家免费技能培训有哪些
  • 网站建设招代理/关键词完整版
  • 做论坛网站/网站收录批量查询
  • 网站app制作平台/cps推广是什么意思
  • 网站源码提取/sem是什么意思啊
  • 新手做啥网站好/济南做网站公司哪家好