1

我们有 2 张桌子。

  1. 表 - XYZ - > 拥有超过 1.89 亿条记录
  2. 表 - ABC - > 只有 1098 条记录。

我们的连接查询有点像

select a.a, a.b, a.c 
from xyz a , ABC r 
where a.d = r.d
    and a.sub not like '0%' 
    and ((a.eff_dat < sysdate) or (a.eff_date is null))

这就是我们的查询的执行方式。无论如何都可以优化它以更快地执行。除了不喜欢,你能建议我任何其他方法吗?

在解释计划中,我看到它以 189 M 作为迭代器并检查 1098 条记录,这需要更多时间。我在 from 关键字之后交换了表格,但它也不起作用。尝试了领先的提示,这也没有达到目的。广告列也是一个索引列,也用于提示。

请建议任何优化方法。

4

2 回答 2

4

当您在表上有多个谓词时,例如:

    a.sub not like '0%' 
and ((a.eff_dat < sysdate) or (a.eff_date is null))

...除非您使用动态采样,否则优化器不太可能准确估计结果集的基数,因此请检查解释计划以查看是否:

  1. 正在调用动态采样。
  2. 基数的估计是正确的。

如果谓词不是很有选择性——如果它们没有消除大约 90% 的东西或表中的行——那么索引不太可能有助于查找行,并且完全扫描 (如果表以支持的方式进行分区,则使用分区修剪)可能是最佳访问路径。

我有理由确定,如果表之间存在外键(即所有 ad 的值都存在于 rd 中),那么最佳访问路径将是对 XYZ 进行完整扫描,并与 ABC 进行哈希连接。顺便说一句,您提到了提示,但没有将它们包含在问题中。用假名隐藏表的用途也无济于事,因为这些名称通常会提供有关数据类型和数据集中值分布的有价值的线索。

于 2013-09-11T15:44:02.850 回答
1

似乎大部分成本将用于对大表进行(假定的)全表扫描。我建议重写您的 WHERE 条件,如下所示:

SELECT * FROM XYZ A
WHERE SUBSTR(A.SUB, 1, 1) <> '0'
AND NVL(A.EFF_DAT, TO_DATE('01-01-0001', 'MM-DD-YYYY')) < SYSDATE ;

然后创建一个包含所有相关列的函数索引:

CREATE INDEX IX_XYZ1 ON
XYZ(NVL(EFF_DAT, TO_DATE('01-01-0001', 'MM-DD-YYYY')), SUB, D);

通过检查执行计划,确保基于成本的优化器正在获取新索引。

LIKE、NOT LIKE 和 OR 操作数是您可以在 WHERE 条件下使用的一些最糟糕的东西。

于 2013-09-12T01:51:22.507 回答