gpt4 book ai didi

sql - 选择顶行时使用了错误的索引

转载 作者:行者123 更新时间:2023-12-03 15:40:02 25 4
gpt4 key购买 nike

我有一个简单的查询,它选择由其他索引列过滤的列之一排序的前 200 行。困惑是为什么PL/SQL Developer中的查询计划显示使用了这个索引只有当我选择所有行时,例如:

SELECT * FROM
(
SELECT *
FROM cr_proposalsearch ps
WHERE UPPER(ps.customerpostcode) like 'MK3%'
ORDER BY ps.ProposalNumber DESC
)
WHERE ROWNUM <= 200

计划显示它使用索引CR_PROPOSALSEARCH_I1,它是两列的索引:PROPOSALNUMBER & UPPER(CUSTOMERNAME),这需要 0.985s 执行:
query with ROWNUM

如果我摆脱了 ROWNUM 条件,计划就是我所期望的,它会在 中执行0.343s :
query without ROWNUM

哪里 index XIF25CR_PROPOSALSEARCH is on CR_PROPOSALSEARCH (UPPER(CUSTOMERPOSTCODE));
怎么来的?

编辑 : 我收集了 cr_proposalsearch 的统计数据表和两个查询计划现在都显示它们使用 XIF25CR_PROPOSALSEARCH指数。

最佳答案

包括 ROWNUM 会更改优化器关于哪个是更有效路径的计算。

当您执行这样的 top-n 查询时,并不一定意味着 Oracle 将获取所有行,对它们进行完全排序,然后返回顶部的行。 COUNT STOPKEY执行计划中的操作表示 Oracle 只会执行底层操作,直到找到您要求的行数。

优化器计算出完整查询将获取和排序 77K 行。如果它使用这个计划进行 top-n 查询,它必须对这些行进行大量排序才能找到前 200 行(它不一定要对它们进行完全排序,因为它不关心确切的顺序)超过顶部的行数;但它必须查看所有这些行)。

top-n 查询的计划使用另一个索引来完全避免排序。它按顺序考虑每一行,检查它是否与谓词匹配,如果匹配则返回它。当它返回 200 行时,就完成了。它的计算表明,这对于获取少量行会更有效。 (当然,这可能不对;您还没有说明这些查询的相对性能是多少。)

如果优化器在您请求所有行时选择此计划,则它必须按降序读取整个索引,在检查谓词时按 ROWID 从表中获取每一行。这将导致大量额外的 I/O 并检查许多不会返回的行。所以在这种情况下,它决定使用 customerpostcode 上的索引。效率更高。

如果您逐渐增加要从 top-n 查询返回的行数,您可能会发现计划从第一个切换到第二个的临界点。仅从这两个计划的成本来看,我猜这可能是大约 1,200 行。

关于sql - 选择顶行时使用了错误的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6911423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com