在 order by 子句期间使用索引?
Using index during order by clause?
我已经在员工 table 的 created_date 列上创建了索引,但是当我看到下面查询的解释计划时
我没有看到索引被使用。为什么?
Select * from employee order by created_date desc;
根据我的理解,oracle 将以排序的方式(使用 B 树)将创建日期与行 ID 一起保存。所以
为什么它不使用已经排序的数据然后使用行 ID 获取其他数据?
如果不使用索引,那么它会获取内存中的所有数据,然后对其进行排序并return。不是吗?
很可能您的 created_date
列可以为空。添加
where created_date is not null
您的查询,
Select * from employee where created_date is not null
order by
created_date desc;
再看看你的 explain plan
。
不保证使用索引,但如果不需要全扫描,很有可能使用。 (如果查询returns超过百分之十,一般不需要索引)
Oracle 检查数据大小(我们可以从 dba_tables
查询,也可以手动查询),如果 CBO
(Cost based optimization
,在大多数系统中,这种类型的优化是首选,而不是 Rule-based optimization
) 使用,相关 table 分析。
CBO
使用数据库统计生成多个execution
plans
,选择成本最低的一个,成本与
完成操作所需的系统资源。
您必须从 table 开始读取所有行,对吗?要从磁盘中读取所有这些,最快的方法是批量读取它们 - 逐块读取它们,而不管它们在磁盘上的顺序如何。这将最大限度地减少从硬盘读取的次数。
您的提议:
看指数。查找具有最新日期的行的 rowid 并从磁盘读取该行。然后找到下一行的 rowid 并从磁盘读取该行。重复。 table.
中的每一行从磁盘读取一次
是的,这样您就已经对行进行了排序(您避免了 CPU 对行进行排序的工作)。但是你有更多的磁盘读取操作。只是为了弥补一些数字:您节省了 0.8 秒的 CPU 工作,并且将 I/O 时间增加了 40 秒。 (纯属编造,但大概是比较正确的数量级。)
我已经在员工 table 的 created_date 列上创建了索引,但是当我看到下面查询的解释计划时 我没有看到索引被使用。为什么?
Select * from employee order by created_date desc;
根据我的理解,oracle 将以排序的方式(使用 B 树)将创建日期与行 ID 一起保存。所以 为什么它不使用已经排序的数据然后使用行 ID 获取其他数据?
如果不使用索引,那么它会获取内存中的所有数据,然后对其进行排序并return。不是吗?
很可能您的 created_date
列可以为空。添加
where created_date is not null
您的查询,
Select * from employee
where created_date is not null
order by created_date desc;
再看看你的 explain plan
。
不保证使用索引,但如果不需要全扫描,很有可能使用。 (如果查询returns超过百分之十,一般不需要索引)
Oracle 检查数据大小(我们可以从 dba_tables
查询,也可以手动查询),如果 CBO
(Cost based optimization
,在大多数系统中,这种类型的优化是首选,而不是 Rule-based optimization
) 使用,相关 table 分析。
CBO
使用数据库统计生成多个execution plans
,选择成本最低的一个,成本与 完成操作所需的系统资源。
您必须从 table 开始读取所有行,对吗?要从磁盘中读取所有这些,最快的方法是批量读取它们 - 逐块读取它们,而不管它们在磁盘上的顺序如何。这将最大限度地减少从硬盘读取的次数。
您的提议:
看指数。查找具有最新日期的行的 rowid 并从磁盘读取该行。然后找到下一行的 rowid 并从磁盘读取该行。重复。 table.
中的每一行从磁盘读取一次是的,这样您就已经对行进行了排序(您避免了 CPU 对行进行排序的工作)。但是你有更多的磁盘读取操作。只是为了弥补一些数字:您节省了 0.8 秒的 CPU 工作,并且将 I/O 时间增加了 40 秒。 (纯属编造,但大概是比较正确的数量级。)