【发布时间】:2011-12-30 22:56:23
【问题描述】:
我一直在学习 Oracle SQL 中的索引,我想用一个测试表做一个小实验,看看索引是如何工作的。正如我从之前的一篇文章中发现的那样,最好的方法是使用 EXPLAIN PLAN。但是,我遇到了一些让我感到困惑的事情。
我的示例表包含属性(EmpID、Fname、Lname、Occupation 等)。我使用我编写的 java 程序(随机名称、职业等)填充了 500,000 条记录。现在,这里有一些带索引和不带索引的示例查询:
没有索引:
SELECT Fname FROM EMPLOYEE WHERE Occupation = 'DOCTOR';
解释计划说:
OPERATION OPTIMIZER COST
TABLE ACCESS(FULL) TEST.EMPLOYEE ANALYZED 1169
现在我创建索引:
CREATE INDEX occupation_idx
ON EMPLOYEE (Occupation);
带有索引“occupation_idx”:
SELECT Fname FROM EMPLOYEE WHERE Occupation = 'DOCTOR';
解释计划说:
OPERATION OPTIMIZER COST
TABLE ACCESS(FULL) TEST.EMPLOYEE ANALYZED 1169
所以...成本还是一样,1169?现在我试试这个:
带有索引“occupation_idx”:
SELECT Occupation FROM EMPLOYEE WHERE Occupation = 'DOCTOR';
解释计划说:
OPERATION OPTIMIZER COST
INDEX(RANGE SCAN) TEST.OCCUPATION_IDX ANALYZED 67
因此,似乎仅当该列是我从中提取值的唯一列时才使用索引。但是我认为索引的目的是使用索引列作为键来解锁整个记录?上面的搜索是一个毫无意义的搜索......它搜索你已经知道的值。我能想到的唯一有价值的查询仅涉及索引列的值(而不是记录的其余部分)将是聚合,例如 COUNT 或其他东西。
我错过了什么?
【问题讨论】:
-
有趣的问题,我很想知道为什么会这样。
-
是否为
EMPLOYEE表定义了主键? -
索引可能没有完成构建吗?如果您重新运行查询 SELECT Fname FROM EMPLOYEE WHERE Occupation = 'DOCTOR';它的成本下降了吗?
-
@OMGPonies:不,其实没有PK,但是我加了一个,然后drop掉重新创建索引,结果还是一样。
-
@xQbert:不,这不会改变任何事情。不过还是谢谢。
标签: sql oracle database-design