【发布时间】:2021-07-17 12:05:56
【问题描述】:
我正在尝试将历史源表与新维度表的每日快照对齐。 我终于让我的查询做我想做的事,但我在两个等效版本之间的性能调整上苦苦挣扎。我在一个无法访问 Prod 的开发环境中,所以我的测试是不现实的(结果是立竿见影的)。 prod 环境将有数百万行和数十列,每个字段都有多个历史版本,因此性能很重要。当然,DBA 会审查性能,但这需要一些时间,我想了解幕后发生的事情。
对于下面的代码,请注意 A、B、C 和 X 共享一个键,X 仅具有键的子集(需要左连接),Y 具有 X 的描述信息(并且没有主键)。
我的查询运行如下:
Select
A.field,
B.field,
C.field,
nvl(X.field,valueIfNull), --nvl is the oracle equivalent of coalesce
nvl(Y.field,valueIfNull)
from tableA A
inner join tables BCD B, C, D
on A.key = B.key
and A.date<= B.date < A.date
... do this 3 times for B, C & D...
现在我看到了两个选项(并且有效)
left join tableX X
on A.key = X.key and A.date = X.date -- this will yield null values -> left join -> ok
left join tableY Y
on Y.key = nvl(**X**.key,'~') and Y.date = X.date
where Y.status in ('statusFlag1');
或者,这也可以:
left join tableX X
on A.key = X.key and A.date = X.date -- this will yield null values -> left join -> ok
left join tableY Y
on Y.key = X.key and Y.date = X.date
where (Y.status in ('statusFlag1') or Y.status is null);
最后一种选择是使用内部查询来计算 Y 和 X 列并加入该列。我还没有添加它,因为它在 imo 中的可读性会降低,但如果它意味着性能改进,我可以添加它。
所以基本上是 nvl 和加入那些“空”值更快,还是在 where 子句中添加空值?还是使用内部查询?我们将有数百万行,mi
【问题讨论】:
-
如问题中所述,因为我无权访问生产,而且我的测试数据是一个非常小的子集,其中两个查询给出完全相同的性能
-
@DawTheDataDawer 。 . .我不认为这些是等价的。很难看出你真正想要什么,但你应该选择正确的逻辑。
-
是的,Martin schapendonk 在下面的答案中明确表示,我的情况不能转置为简单的等价物。我将使用最普遍适用的逻辑(没有 nvl)并等待 BDA 验证查询
标签: sql oracle query-optimization