oracle 索引列会降低大型数据集的分页速度

oyxsuwqo  于 2023-05-06  发布在  Oracle
关注(0)|答案(1)|浏览(144)

我们有一个表,它有三列的索引,比如按升序排列的A、B、C列。
我们需要检索分页的数据。
这是一个大于1.5亿行的大表。
我们使用的查询是这样的:

select * from large_table order by A, B, C fetch first 100 rows only;

这几乎需要2分钟的时间来运行,原因是订单的时间太长了。
这里我的问题是,如果列在索引中已经排序了,为什么Oracle还要尝试对列进行排序?为什么它不先读取索引并获取100行,而不尝试按完整的数据集进行排序?是否有一种方法可以根据索引读取行?
注意:我也尝试将索引替换为BTree索引,但没有改进。

zi8p0yeb

zi8p0yeb1#

为了使Oracle在查询不对索引列应用任何 predicate 时考虑使用索引,必须将至少一个索引列定义为NOT NULL。如果所有的索引列都是NULL,那么在没有查询 predicate 的情况下,索引列中所有NULL的行都是你想要检索的候选行,但是这样的行不能通过索引找到,因为Oracle不会在b树索引中存储这样的all-NULL键值。因此,Oracle无法安全地使用索引来查找您所请求的行。
话虽如此,即使有一个可行的索引,Oracle也可能不会选择使用它,而更喜欢全表扫描,特别是如果您在SELECT子句中要求一些非索引列。如果发生这种情况并且统计信息收集没有修复,您可以通过提示强制使用索引:

SELECT /*+ INDEX(large_table indexname_on_largetable) */ . . .

为了获得索引的排序优势,ORDER BY必须以正确的顺序和索引扫描的相同方向(例如:ORDER BY ASC需要INDEX_ASC(默认值),但ORDER BY DESC需要INDEX_DESC

相关问题