我在employee表的created_date列上创建了索引,但是当我看到下面查询的解释计划时 我没有看到使用索引。为什么?
Select * from employee order by created_date desc;
根据我的理解,oracle将以排序的方式(使用B树)和行id保持创建的日期。所以 为什么它不使用已经排序的数据然后使用行ID?
获取其他数据如果它不使用索引,那么它将获取内存中的所有数据,然后对其进行排序并返回它。不是吗?
答案 0 :(得分:1)
很可能您的created_date
列可以为空。添加
where created_date is not null
查询,
从员工
where created_date is not null
中选择* created_date desc;
然后再次查看explain plan
。
不保证使用索引,但如果它不需要全扫描,则最有可能使用索引。 (如果查询返回超过10%,通常不需要索引)
Oracle检查数据量级(我们也可以手动查询dba_tables
),如果CBO
(Cost based optimization
,在大多数系统中,这种类型的优化是首选,而不是使用了Rule-based optimization
),并对相关表格进行了分析。
CBO
使用数据库统计信息生成多个execution
plans
,选择费用最低的一个,其中费用与
完成操作所需的系统资源。答案 1 :(得分:1)
你必须读取基表中的所有行,对吗?要从磁盘中读取所有这些内容,最快的方法是逐块读取它们 - 无论它们在磁盘上的排序如何。这将最大限度地减少从硬盘读取的数量。
您提出的建议:
看看索引。找到具有最新日期的行的rowid,并从磁盘读取该行。然后找到下一行的rowid并从磁盘读取该行。重复。一个从磁盘读取表中的每一行。
是的,以这种方式你已经订购了行(你可以避免CPU工作来订购行)。但是你有更多的磁盘读取操作。只是为了弥补一些数字:你节省了0.8秒的CPU工作量,并且你将I / O时间增加了40秒。 (纯粹组成,但在比较中可能是正确的数量级。)