gpt4 book ai didi

Oracle:使用全扫描代替复合索引

转载 作者:行者123 更新时间:2023-12-04 06:36:49 26 4
gpt4 key购买 nike

我有奇怪的 oracle 优化器行为:

SELECT a.id,
a.date_insert,
a.message#cnt
FROM T_MESSAGE_TRANSMIT A,
T_LIST l
WHERE a.priority_id = 0
AND a.status = 'Q'
and l.id = a.list_id

此查询在 T_MESSAGE_TRANSMIT 上生成全扫描,不管它是一个索引覆盖的事实 priority_idstatus领域:
CREATE BITMAP INDEX INFORMER.IX$MESSAGE_TRANSMIT$6 ON INFORMER.T_MESSAGE_TRANSMIT (STATUS, PRIORITY_ID)

表大小约为 28M 行,并且在 7 天前已经分析过(从那天起只添加了数千行)。

如果我使用提示 /*+index(a IX$MESSAGE_TRANSMIT$6) */那么一切都会变得很好,以及如果我删除连接,并将查询重写为:
SELECT a.id,
a.date_insert,
a.message#cnt
FROM T_MESSAGE_TRANSMIT A,
WHERE a.priority_id = 0
AND a.status = 'Q'

我哪里会出错?

UPD :

问题出在此优化器设置中:
optimizer_mode  first_rows_10

最佳答案

符合优先级 id/status 标准的行比例是多少?

例如,如果 20% 的行匹配,那么它必须在 20% 的情况下访问该行以获取额外的详细信息。如果它正在访问 20% 的行,它可能会访问 80-90% 的块。在这种情况下,忽略索引是正确的。

但是,如果它在没有连接的情况下为查询使用索引,则更有可能是由于 a.list_id 值。如果它使用 BITMAP 索引,对于它在那里找到的每一行,它必须通过 id 访问 T_LIST 表。如果 T_LIST 很大并且 id 没有被索引,那么这可能意味着重复 T_LIST 的完整扫描是一个坏主意。

在这种情况下,它可能会从 T_MESSAGE_TRANSMIT 获取所有匹配的行,按 ID 对它们进行排序,然后从 T_LIST 获取匹配的行。到 T_LIST 的散列连接也可能是合适的。

另外,你确定你不是简单的想做一个

SELECT a.id,
a.date_insert,
a.message#cnt
FROM T_MESSAGE_TRANSMIT A
WHERE a.priority_id = 0
AND a.status = 'Q'
AND a.list_id in (select l.id from T_LIST l)

如果 id 在 T_LIST 上不是唯一的,您的原始 SQL 将生成重复项。

关于Oracle:使用全扫描代替复合索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4778546/

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