0

我有一些表格的查询:

select * from MAIN.MY_TABLE 
    where ID in (select ID from OTHER.OTHER_TABLE where type = 'BANANA');

在哪里ID被索引MAIN.MYTABLE,但没有被索引OTHER.OTHER_TABLE

最近这些一直在与ORA-01555: snapshot too old.

我的理解是这是由于查询对于撤消空间花费的时间太长。

这很可能是因为它是业务旺季并且数据库负载很重。

问题是,如果我要将查询拆分为表单的几个查询:

select * from MAIN.MY_TABLE 
    where ID in (select ID from OTHER.OTHER_TABLE where type = 'BANANA') 
        and ID >= 0 and ID <1000;

select * from MAIN.MY_TABLE 
    where ID in (select ID from OTHER.OTHER_TABLE where type = 'BANANA') 
        and ID >= 1000 and ID <2000;

select * from MAIN.MY_TABLE 
    where ID in (select ID from OTHER.OTHER_TABLE where type = 'BANANA') 
        and ID >= 2000 and ID <3000;

一方面,这似乎每个查询都比初始查询花费的时间更少。另一方面,这似乎是一个明显的优化,我认为甲骨文无论如何都会这样做。

4

2 回答 2

1

与 MY_TABLE 中的行数相比,此查询假设返回多少行?

如果行数中的行数(从 OTHER.OTHER_TABLE 中选择不同的 ID,其中 type = 'BANANA')约为 MY_TABLE 中行数的 2-5%,则 MY_TABLE.ID 上的索引将有所帮助。

所以我会先检查这些数字。我会尝试这样的查询:

select * 
from MAIN.MY_TABLE a,
     (select distinct ID from OTHER.OTHER_TABLE where type = 'BANANA') b
where a.id = b.id;

如果为真,并且使用了 MY_TABLE 上的索引(根据执行计划),我将检查执行速度(从 OTHER.OTHER_TABLE 中选择不同的 ID,其中 type = 'BANANA'):

select count(1)
from
(select distinct ID from OTHER.OTHER_TABLE where type = 'BANANA')

PS 要在 sqlplus 中获得真正的执行计划:

set linesize 200
set autotrace traceonly
    select * 
    from MAIN.MY_TABLE a,
         (select distinct ID from OTHER.OTHER_TABLE where type = 'BANANA') b
    where a.id = b.id;
于 2014-06-26T04:17:02.453 回答
1

你为什么不尝试优化查询,这样它就不会花这么长时间?对于初学者,如果您使用 IN (SELECT...) 而不是连接,Oracle 可能很难构建一个好的查询计划。此查询是否以更好的查询计划返回相同的结果(即JOIN运算符而不是IN运算符):

select * from MAIN.MY_TABLE 
inner join
OTHER.OTHER_TABLE 
on MAIN.MY_TABLE.ID = OTHER.OTHER_TABLE.ID
and OTHER.OTHER_TABLE.type = 'BANANA';

OTHER.OTHER_TABLE唯一的问题是列中是否有重复项ID。这将导致最终结果集中重复计算。但是如果可能的话,你真的应该避免这种IN (SELECT....)结构。

于 2014-06-26T02:27:41.590 回答