在order by子句中使用索引?

时间:2017-11-15 16:55:49

标签: oracle indexing sql-order-by query-optimization

我在employee表的created_date列上创建了索引,但是当我看到下面查询的解释计划时 我没有看到使用索引。为什么?

    Select * from employee order by created_date desc;

根据我的理解,oracle将以排序的方式(使用B树)和行id保持创建的日期。所以 为什么它不使用已经排序的数据然后使用行ID?

获取其他数据

如果它不使用索引,那么它将获取内存中的所有数据,然后对其进行排序并返回它。不是吗?

2 个答案:

答案 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),如果CBOCost based optimization,在大多数系统中,这种类型的优化是首选,而不是使用了Rule-based optimization),并对相关表格进行了分析。

  • CBO使用数据库统计信息生成多个execution plans,选择费用最低的一个,其中费用与 完成操作所需的系统资源。

答案 1 :(得分:1)

你必须读取基表中的所有行,对吗?要从磁盘中读取所有这些内容,最快的方法是逐块读取它们 - 无论它们在磁盘上的排序如何。这将最大限度地减少从硬盘读取的数量。

您提出的建议:

看看索引。找到具有最新日期的行的rowid,并从磁盘读取该行。然后找到下一行的rowid并从磁盘读取该行。重复。一个从磁盘读取表中的每一行。

是的,以这种方式你已经订购了行(你可以避免CPU工作来订购行)。但是你有更多的磁盘读取操作。只是为了弥补一些数字:你节省了0.8秒的CPU工作量,并且你将I / O时间增加了40秒。 (纯粹组成,但在比较中可能是正确的数量级。)