Oracle 11g,如何加快“in”查询
Posted
技术标签:
【中文标题】Oracle 11g,如何加快“in”查询【英文标题】:Oracle 11g, how to speed up an 'in' query 【发布时间】:2016-05-18 07:37:27 【问题描述】:我试图创建一个视图并且需要创建一个列来显示“somenumber”列是否存在于其他表中。下面的代码工作但非常缓慢。是否可以将表声明为(从veryYugeTable 中选择一些数字)并检查该表,而不是为每条记录发送此查询或使用其他方式来加快查看速度?
case
when someOtherTable.someNumber in(select someNumber from veryYugeTable) then 'exists'
else 'doesn't exist'
end as "someColumn"
【问题讨论】:
在 someNumber = someOtherTable.someNumber 上使用 left joinveryYugeTable 然后将 casewhen 子句更改为veryYugeTable.Column is null then '不存在' else 'exits' 请发布视图查询及其解释计划。没有看到问题不容易提供解决方案。请参阅here 一些提示。 【参考方案1】:查询看起来不错。您应该在veryYugeTable.someNumber
上有一个索引。
有时优化器处理相关子查询比处理非相关子查询更好,因此您可以尝试:
case
when exists
(
select *
from veryYugeTable
where veryYugeTable.someNumber = someOtherTable.someNumber
) then 'exists'
else 'doesn''t exist'
end as "someColumn"
(好吧,因为这个查询和你的完全一样,优化器应该得到相同的执行计划,但情况并非总是如此。)
但如前所述:确保首先拥有该索引。
【讨论】:
谢谢,索引似乎是个好主意。【参考方案2】:如果您执行以下操作,您可能会发现标量子查询缓存会带来一些好处:
coalesce((select 'exists'
from veryyugetable vyt
where vyt.somenumber = someOtherTable.someNumber
and rownum = 1),
'doesn''t exist') somecolumn
注意如果vyt.somenumber
是唯一列,则不需要and rownum = 1
。另外,我建议索引vyt.somenumber
列。
【讨论】:
【参考方案3】:使用左连接而不是将 in 子句放在 select 中:
left join veryYugeTable on someNumber = someOtherTable.someNumber
调整你的 case when 语句如下:
case
when veryYugeTable.OtherColumn is null then 'doesn''t exist'
else 'exist'
end as "someColumn"
【讨论】:
如果someNumber
不是veryYugeTable
表中的PK(唯一),这将失败(= 产生重复)
遗憾的是 someNumber 在veryYugeTable 不是PK。以上是关于Oracle 11g,如何加快“in”查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在 oracle db 11g - centos 6 中启用查询日志