You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何此查询执行TABLE ACCESS FULL而非FULL INDEX SCAN?

为什么查询select col2,col3 from indextest走全表扫描而非全索引扫描?

先还原下你的操作步骤:

  • 创建表与复合索引:
    create table indexTest( col1 NUMBER, col2 NUMBER, COL3 NUMBER);
    create index indexTest_INX on indexTest(col2,col3);
    
  • 验证索引结构:analyze index indexTest_INX validate structure;
  • 执行查询:select col2,col3 from indextest;

但执行计划显示TABLE ACCESS FULL,而非预期的FULL INDEX SCAN,主要有这几个常见原因:

1. 表的数据量过小,优化器选择更高效的全表扫描

Oracle的成本优化器(CBO)会计算不同执行路径的成本。如果你的indexTest表是空表或者只有几行数据,全表扫描的IO成本会比读取索引更低——毕竟索引本身也是需要磁盘IO的,小表直接扫表反而更快。

你可以插入一批测试数据(比如几千行),再重新查看执行计划,大概率会切换到全索引扫描。

2. 表的统计信息缺失或过时

CBO完全依赖准确的统计信息来判断执行路径的优劣。如果表创建后从未收集过统计信息,或者数据量发生了大幅变化但没更新统计,优化器可能无法准确评估索引的价值,默认选择全表扫描。

你可以手动收集统计信息试试:

exec dbms_stats.gather_table_stats(ownname => '你的用户名', tabname => 'INDEXTEST');

收集完成后重新执行查询,再观察执行计划的变化。

3. 优化器参数或模式影响了成本计算

有些参数会直接影响优化器对索引成本的判断,比如optimizer_index_cost_adj(默认值为100,值越高索引的相对成本越高,优化器越不容易选择索引);如果你的数据库还在使用早已废弃的RULE(基于规则的优化器)模式,也可能不会优先选择索引路径。

你可以先查看当前优化器模式:

select value from v$parameter where name = 'optimizer_mode';

如果是RULE模式,建议改成ALL_ROWS或FIRST_ROWS模式;如果是CBO模式,可以适当调低optimizer_index_cost_adj参数来降低索引的相对成本。

4. 索引可用性问题(可能性较低)

虽然你执行了analyze index ... validate structure,但还是可以确认下索引的状态:

select status from user_indexes where index_name = 'INDEXTEST_INX';

如果状态不是VALID,说明索引失效,优化器自然不会选用它。不过你已经做了结构验证,这种情况概率很低。


内容的提问来源于stack exchange,提问作者Sourav Deb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:29:35