0

为什么第一个查询使用全表扫描,而第二个使用索引?

SELECT * 
FROM   emp
WHERE  job = 'PRESIDENT';

SELECT job 
FROM   emp
WHERE  job = 'PRESIDENT';
4

2 回答 2

2

很简单,因为优化器已经计算出第一次查询的全扫描成本低于基于索引的访问方法的成本。

这似乎是一种不太可能的情况,因为您本能地希望只有一行与 job = 'PRESIDENT' 条件匹配,但如果您想象 50% 的行与该条件匹配,那么使用多块读取读取全表将会比读取索引然后以可能较小的读取方式读取表更快。

在第二个查询的情况下,优化器知道不需要访问表来给出正确的答案,所以除非表非常窄,否则使用索引范围扫描或快速全索引扫描会更快返回结果。

这里教导的教训可能是您应该只返回您需要的列。一个附属的教训是,大多数抽象层(例如 ActiveRecord)默认情况下会比它们需要的慢,因为它们往往总是返回每一列。

于 2013-12-28T13:23:54.290 回答
1

第二个查询仅选择列“job”。当您选择索引时,该列的值是已知的。您的查询不需要其他任何内容,因此无需从表中读取任何其他数据。

对于第一个查询,它更加困难。通常Oracle应该访问索引。此列中有多少个不同的职位?如果基数(即选择性)较低,则全表扫描可以比索引扫描更快。在这种情况下,我们可以假设表中只有 1 个PRESIDENT,但 Oracle 已经根据统计和估计来评估执行计划。对于其他工作,例如'CLERK',我认为全表扫描将是获取数据的禁食。

于 2013-12-28T13:20:35.493 回答