2017-09-15 66 views
2

下面是我的SQL代碼:爲什麼SQL「NOT IN」太慢?

select count(1) 
from customers 
where id in(
    select custid 
    from accounts 
    where sid in(72,73,74,75,76,77,78,79) 
) 
and id not in(
    select custid 
    from accounts 
    where sid in(80,81) 
); 

表都編入索引。此代碼是否可以重寫以獲得更好的性能?

+1

請** [編輯] **您的問題,並添加所涉及的表(包括所有索引),您正在使用的查詢和生成的執行計劃的'create table'語句**解釋(分析,詳細)**。 [**格式化文本**](http://stackoverflow.com/help/formatting)請(請確保您保留縮進),[無屏幕截圖](http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-code-on-so-when-asked-question/285557#285557) –

+1

可以在不改變結果的情況下移除NOT IN標準。請回顧一下您的問題。 –

+1

@PatrickHonorez - 我讀到它的方式,給定的id可能在帳戶表中有多行。如果該表中的id同時具有sid = 72和sid = 80的情況,則不應該計數,因此需要NOT IN – kbball

回答

3

您也可以嘗試存在:

select count(1) 
from customers c 
where exists (
    select 1 
    from accounts a 
    where sid in(72,73,74,75,76,77,78,79) 
    and a.custid = c.custid 
) 
and not exists (
    select 1 
    from accounts a 
    where sid in(80,81) 
    and a.custid = c.custid 
); 

這可能是有益的讀取:Difference between EXISTS and IN in SQL?

+0

WOW!將無法給出正確的結果!我已經在一秒鐘而不是5分鐘的結果! – user3260061

0

加入您的表格而不是使用2個子語句。

SELECT count(1) 
FROM customers c 
INNER JOIN accounts a ON c.id = a.sid 
WHERE id IN (72, 73, 74, 75, 76, 77, 78, 79) 
+0

計數過高,因爲您可能會計算在帳戶中有一行的id(80,81) – kbball

+2

如果客戶擁有多個帳戶 –

0

A減查詢可能會更有效。就像這樣:

SELECT count(1) 
FROM 
(
SELECT c.id 
FROM customers c 
INNER JOIN accounts a ON c.id = a.sid 
WHERE id IN (72, 73, 74, 75, 76, 77, 78, 79) 
MINUS 
SELECT c.id 
FROM customers c 
INNER JOIN accounts a ON c.id = a.sid 
WHERE id IN (80,81) 
) 
+1

我試過這個,但得到了一個語法錯誤 - 接近MINUS。 – user3260061