我正在尝试创建一个视图,并且需要创建一个列,以显示其他表上是否存在“somenumber”列。下面的代码工作但速度很慢。是否可以将表声明为(从veryYugeTable中选择someNumber)并检查该表而不是为每条记录发送此查询或使用其他方式加速视图?
case
when someOtherTable.someNumber in(select someNumber from veryYugeTable) then 'exists'
else 'doesn't exist'
end as "someColumn"
答案 0 :(得分:1)
查询看起来很好。你应该有veryYugeTable.someNumber
的索引。
有时优化器处理相关子查询的效果优于非相关子查询,因此您可以尝试:
case
when exists
(
select *
from veryYugeTable
where veryYugeTable.someNumber = someOtherTable.someNumber
) then 'exists'
else 'doesn''t exist'
end as "someColumn"
(好吧,因为这个查询与你的查询完全相同,优化器应该达到相同的执行计划,但情况并非总是这样。)
但如上所述:确保首先获得该索引。
答案 1 :(得分:0)
使用left join而不是将in子句放在select:
中left join veryYugeTable on someNumber = someOtherTable.someNumber
在陈述时调整您的案例如下:
case
when veryYugeTable.OtherColumn is null then 'doesn''t exist'
else 'exist'
end as "someColumn"
答案 2 :(得分:0)
如果您执行以下操作,您可能会发现标量子查询缓存会带来一些好处:
coalesce((select 'exists'
from veryyugetable vyt
where vyt.somenumber = someOtherTable.someNumber
and rownum = 1),
'doesn''t exist') somecolumn
N.B。如果and rownum = 1
是唯一列,则不需要vyt.somenumber
。此外,我建议索引vyt.somenumber
列。