有什么办法可以加快这个查询吗?

问题描述:

我有两张桌子,一张是另一张的副本。 (我必须删除父项中不存在的记录)。运行此查询可以工作,但需要大约1分钟才能完成。我知道NOT EXISTS速度更快,因为我不会为每行运行子查询,但不会返回任何结果。有什么办法可以加快这个查询吗?

SELECT mlscopy.listing_listnum 
FROM mlscopy 
WHERE mlscopy.listing_listnum 
NOT IN (SELECT mls_cvrmls.listing_listnum FROM mls_cvrmls) 

我会澄清,这里的问题是父母随着时间的变化,我必须从孩子中删除/添加记录。所以我坚持要从child中删除listing_listnum在parent中不存在的地方。

这里是不存在的查询

SELECT mlscopy.listing_listnum 
FROM mlscopy 
WHERE 
NOT EXISTS (SELECT mls_cvrmls.listing_listnum FROM mls_cvrmls) 

想通了

SELECT mlscopy.listing_listnum 
FROM mlscopy 
WHERE NOT EXISTS (
SELECT mls_cvrmls.listing_listnum 
FROM mls_cvrmls 
WHERE mlscopy.listing_listnum = mls_cvrmls.listing_listnum 
) 
+0

“我知道NOT EXISTS比较快,因为我不会运行子查询的每一行,但不返回任何结果。” - 你可以包含你的'not exists'查询吗?如果有的话,它应该比'not in'查询更可靠,因为空值可能在被排除的数据集中。 – 2012-01-16 21:04:05

+0

您的问题的关闭点。但是如何为父表添加触发器来自动维护子表。 – Randy 2012-01-16 21:22:42

+0

嗯..汤姆凯特不会说EXISTS会更快。 http://asktom.oracle.com/pls/asktom/f?p=100:11:4144857323705644::::P11_QUESTION_ID:953229842074 – Benoit 2012-01-17 12:24:59

SELECT mlscopy.listing_listnum 
FROM mlscopy A 
NOT EXISTS 
(
    SELECT * 
    FROM mls_cvrmls B 
    WHERE B.listing_listnum = A.listing_listnum 
); 

试试这个变化,看看它是否是更好:

SELECT mlscopy.listing_listnum 
    FROM mlscopy 
     LEFT JOIN mls_cvrmls 
      ON mlscopy.listing_listnum = mls_cvrmls.listing_listnum 
    WHERE mls_cvrmls.listing_listnum IS NULL 
+0

不知道它会加速,但这可能是我会如何写查询。 – Benoit 2012-01-16 21:01:44

+0

我试过这样的事情,没有返回结果: -/ – 2012-01-16 21:02:38

+1

@AndreDublin - 那么你原来的查询不会返回结果,因为它们在逻辑上是相同的。它们是接近相同结果集的两种不同方式。 – JNK 2012-01-16 21:04:27

试试这个:

CREATE INDEX i_listnum ON mls_cvrmls(listing_listnum ASC) 

试图用LEFT JOINNOT EXISTS重写查询可能不会产生太大的区别,因为查询优化器可以解决这个问题。

然而,通过listing_listnum可以快速找到mls_cvrmls中的一行的方法只能提高性能(但它会占用额外的空间)。

About index creations

另一种选择可能是:

SELECT listing_listnum FROM mlscopy 
MINUS 
SELECT listing_listnum FROM mls_cvrmls