使用减去oracle优化查询

时间:2015-02-28 17:57:23

标签: oracle optimization

希望用减去优化查询来节省太多时间...如果他们能给予感谢帮助。

我有两张桌子A和B,

表A:ID,值

表B:ID

我想要表B中没有的所有表A记录。显示值。 因为它是这样的:

Select ID, value
FROM A
WHERE value> 70
MINUS
Select ID
FROM B;

只有这个查询花了太长时间...任何提示这个简单查询的最佳方法是什么?

感谢您的关注

1 个答案:

答案 0 :(得分:4)

ID和值是否已编入索引?

减号和不存在的表现取决于:

  

这实际上取决于一系列因素。

     

除非有一些,否则MINUS将对两个表进行全表扫描   允许索引的两个查询的where子句中的条件   范围扫描。 A MINUS还要求两个查询都相同   列数,每列与数据类型相同   另一个查询中的相应列(或者一个可转换为   相同类型)。一个MINUS将返回第一个查询中的所有行   第二个查询的列没有完全匹配列。一个   MINUS还需要隐式排序两种查询

     

NOT EXISTS将为外部的每一行读取一次子查询   查询。如果是相关字段(您正在运行相关的   子查询?)是一个索引字段,然后只进行索引扫描。

     

选择使用哪种构造取决于您的数据类型   想要返回,还有两个表/查询的相对大小。   如果外表相对于内表和内表较小   表被索引(优先选择唯一索引但不是必需的)   相关字段,然后NOT EXISTS可能会更快,因为   索引查找将非常快,并且只执行相对较少的   倍。如果两个表的大小大致相同,那么MINUS可能是   更快,特别是如果你只能看到你的领域   正在比较。

Minus operator versus 'not exists' for faster SQL query - Oracle Community Forums

你可以这样使用NOT EXISTS

SELECT a.ID, a.Value
    From a 
    where a.value > 70
    and not exists(
        Select b.ID
        From B
        Where b.ID = a.ID)

编辑:我已经制作了一些虚拟数据和两个数据集用于测试,以证明索引的性能提升。注意:我在MySQL中这样做,因为我的Macbook上没有Oracle。

表A 有2600条记录,包含2列:ID,val。 ID是自动增量整数 Val varchar(255)

表b 有一列,但记录多于表A.自动增量(间隙为3)

如果您愿意,可以重现这一点:Pastebin - SQL Dummy Data

以下是我将要使用的查询:

select a.id, a.val from tablea a
where length(a.val) > 3
and not exists(
    select b.id from tableb b where b.id = a.id
);

没有索引,运行时 986ms ,有1685行。

现在我们添加索引:

ALTER TABLE `tablea` ADD INDEX `id` (`id`);
ALTER TABLE `tableb` ADD INDEX `id` (`id`);

使用索引,运行时 14ms ,有1685行。没有索引的时间是 1.42%