Eri*_*art 5 performance index oracle statistics
我对以下类型的 Oracle 11g 进行了查询,这导致了一系列非常低效的全表扫描:
select t.Id, t.ObjectId, t...[other Tasks columns]
, od1...[ObjectData1 columns]
, od2...[ObjectData2 columns]
from Tasks t
left join ObjectData1 od1 on t.ObjectId=od1.ObjectId
left join ObjectData2 od2 ...
... [more leftjoins] ...
where t.ObjectId = 12345
or t.Id in (
select TaskId from ObjectAffectingTasks where ObjectId=12345
)
Run Code Online (Sandbox Code Playgroud)
任务在 Id、ObjectId 上有索引;ObjectAffectingTasks在 ObjectId 和 TaskId 上都有索引。所有连接的表也有适当的索引。该ObjectAffectingTasks表包含任务ID影响的对象,但对象ID有另一个,所以影响对象ID为12345的所有任务应选择。
在分析查询时,似乎是 OR 条件破坏了执行计划。只有 ObjectId 或只有子查询的 where 子句使用了所有索引。另一种解决方法是创建一个 Union 子查询,它也使用索引:
where t.Id in (
select TaskId from ObjectAffectingTasks where ObjectId=12345
union
select Id from Tasks where ObjectId = 12345
)
Run Code Online (Sandbox Code Playgroud)
无论如何,我希望将原始查询和 IN 子查询转换为对 Id 和 ObjectId 进行索引查找的半连接。但是,我看到 IN 子查询在内部转换为 EXISTS(从...中选择 0)
这可能只是一个统计问题,还是 OR 条件会破坏这一切?是否可以使用这样的 OR 条件查找Tasks和ObjectAffectingTasks上的索引?
不幸的是,查询是由相当复杂的程序代码创建的,因此重写它们将是太多的工作。另一个问题是它们有点通用,可用于 Oracle 和 MS SQL Server,因此索引使用的专有提示也不是一种选择。
小智 2
我在 Oracle 12c 中遇到了非常类似的问题。在实验中,PRECOMPUTE_SUBQUERY 优化器提示“强制”首先执行子查询,从而利用定义的索引。在您的代码片段中,它看起来像这样:
...
where t.ObjectId = 12345
or t.Id in (
select /*+ PRECOMPUTE_SUBQUERY */ TaskId
from ObjectAffectingTasks where ObjectId=12345
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3109 次 |
最近记录: |