跳至主要內容

常见的数据访问方法

ZiSu约 898 字大约 3 分钟

常见的数据访问方法

MySQLOracle 中使用 EXPLAIN 分析 SQL 查询时,索引访问方法(也叫访问路径)是优化 SQL 性能的关键。不同的索引访问方式直接影响查询效率,
下面我们详细讲解 MySQL 和 Oracle 中可能出现的各种索引访问方式,便于你更好地理解和优化 SQL。


✅ 一、MySQL 索引访问方法(重点看 type 字段)

EXPLAIN 输出中,type 表示 访问类型(access type),从好到坏排列如下:

type说明是否使用索引备注
system表仅有一行,系统表极少出现
const通过主键或唯一索引查询常量值查询结果最多一行
eq_ref每次只返回一条匹配记录用于主键或唯一索引连接
ref非唯一索引匹配,可能返回多行最常见的索引连接类型
fulltext全文索引搜索用于 MATCH() AGAINST()
ref_or_nullref 扫描 + NULL 检查少见
index_merge合并多个索引会显示使用了哪几个索引
range范围扫描(BETWEEN、>、<、IN)使用索引的区间查询
index遍历整个索引(不访问表)相比 ALL 效率稍高
ALL全表扫描最低效,尽量避免

🔍 示例说明:

-- const 类型
SELECT * FROM users WHERE id = 1;  -- 主键查询

-- eq_ref 类型
SELECT * FROM orders o JOIN users u ON o.user_id = u.id;

-- ref 类型
SELECT * FROM users WHERE name = 'Tom';  -- name 上有普通索引

-- range 类型
SELECT * FROM users WHERE age BETWEEN 20 AND 30;

-- index_merge 类型
SELECT * FROM users WHERE name = 'Tom' OR age = 30;  -- name 和 age 上都有索引

✅ 二、Oracle 索引访问方法(重点看 Operation + Options

在 Oracle 中使用 EXPLAIN PLANDBMS_XPLAN.DISPLAY() 查看执行计划,关注以下访问方法:

Operation + Options描述是否回表性能
INDEX UNIQUE SCAN唯一索引精确匹配可能非常快
INDEX RANGE SCAN范围扫描可能高效
INDEX FULL SCAN全索引扫描(顺序遍历整个索引)一般用于避免排序或覆盖索引
INDEX FAST FULL SCAN快速索引全扫描(随机读)不保证顺序,适合覆盖索引
INDEX SKIP SCAN跳跃扫描比全表快,低于 range
BITMAP INDEX SCAN位图索引扫描适合多条件查询
TABLE ACCESS BY INDEX ROWID回表取数据索引不覆盖字段时发生
TABLE ACCESS FULL全表扫描最慢,优化重点

🔍 示例说明:

-- 唯一索引扫描(INDEX UNIQUE SCAN)
SELECT * FROM employees WHERE emp_id = 100;

-- 范围索引扫描(INDEX RANGE SCAN)
SELECT * FROM employees WHERE hire_date > TO_DATE('2020-01-01', 'YYYY-MM-DD');

-- 全索引扫描(INDEX FULL SCAN)
SELECT emp_id FROM employees ORDER BY emp_id;

-- 快速全索引扫描(INDEX FAST FULL SCAN)
SELECT emp_id FROM employees;  -- emp_id 是索引列,且覆盖查询

-- 跳跃扫描(INDEX SKIP SCAN)
SELECT * FROM employees WHERE department_id = 10;
-- 若有 (last_name, department_id) 的组合索引,但未用最左列

🆚 MySQL 与 Oracle 索引访问方式对照表:

MySQL typeOracle Operation相似含义说明
constINDEX UNIQUE SCAN主键/唯一值查询
eq_refINDEX UNIQUE SCAN + TABLE ACCESS BY INDEX ROWID唯一值关联
refINDEX RANGE SCAN普通索引查找
rangeINDEX RANGE SCAN范围条件
indexINDEX FULL SCAN遍历索引全部值
ALLTABLE ACCESS FULL全表扫描

🧠 小结优化建议:

  • 首选访问方式:MySQL 中尽量让 typeconst, eq_ref, ref, Oracle 中优选 INDEX UNIQUE/RANGE SCAN
  • 避免访问方式ALL(MySQL)或 TABLE ACCESS FULL(Oracle),会导致全表扫描。
  • 索引设计要点
    • 保证选择性高的列建索引
    • 组合索引遵守最左前缀原则
    • 查询字段尽量使用覆盖索引
    • 尽量避免对索引列使用函数或类型转换

上次编辑于:
贡献者: SuWeiMing