【问题标题】:Avoid full table scan by a different select避免通过不同的选择进行全表扫描
【发布时间】:2013-12-28 11:42:11
【问题描述】:

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

SELECT * 
FROM   emp
WHERE  job = 'PRESIDENT';

SELECT job 
FROM   emp
WHERE  job = 'PRESIDENT';

【问题讨论】:

  • 因为数据库优化器做得不好?如何知道是否发生了全表扫描?您使用的是哪个 DBMS?
  • 1) 什么数据库 2) 你怎么知道查询 1 正在使用全表扫描? 3) 分享您的创建表结构 4) 告诉 emp 有多少记录...并且查询 2 最有可能使用带有覆盖索引的全索引扫描..
  • 1. ORACLE 2. 这是硬件问题

标签: performance oracle full-table-scan


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-01-12
      • 1970-01-01
      • 1970-01-01
      • 2019-07-17
      • 2015-12-04
      • 2014-02-07
      • 1970-01-01
      相关资源
      最近更新 更多