2011-03-16 57 views
3

下面的查詢需要太多的時間,最有可能的。SQL查詢「不」條款的執行「不中」的使用需要,因爲太長

你可以提出任何改進的地方?

SELECT vcode, 
     vname, 
     1014 AS fid 
FROM testcodes co 
WHERE co.vcode NOT IN (SELECT dict.vcode 
         FROM datadictionary dict 
         WHERE dict.fid = 1014) 

有關結構的一點是。 vCode,vName是varchar 和testCodes和DataDictionary具有相同的結構。

我搜索這個問題,發現左連接都不可能解決這個問題? (爲什麼它做得更好,如何做到)?

可有人引導,如果它能夠提高???

回答

7
SELECT vcode, 
     vname, 
     1014 AS fid 
FROM testcodes co 
     LEFT JOIN datadictionary dict 
     ON co.vcode = dict.vcode 
      AND dict.fid = 1014 
WHERE dict.vcode IS NULL 

您必須對創建索引:

  • (testcodes.vcode)
  • (datadictionary.vcode,datadictionary.fid)

兩個做一個索引掃描在每個表上,但IN有一個合併連接,並且INNER JOIN有一個哈希匹配。

+4

至於爲什麼它的速度更快:在'LEFT JOIN'語法告訴查詢優化器如何聯接表的更直接的方式,而'NOT IN(SELECT ...)'是更靈活,但需要從更多的工作數據庫引擎。 – geekosaur 2011-03-16 07:30:02

+0

即使沒有索引。查詢運行DAMN FAST。我寫的查詢花了一分多鐘甚至僅僅幾千條記錄(在數據字典中幾乎10K,在測試代碼中3K) – Umer 2011-03-16 07:39:58

+0

順便說一句,感謝這樣的編輯,我總是會混淆如何縮進那些sql腳本:) – Umer 2011-03-16 07:41:19

0

該查詢看起來沒問題。 嘗試添加以下指標

數據字典指數(FID,VCODE)
testCodes指數(VCODE)

+0

查詢不正常,因爲它不以優化的方式使用索引。 – Pentium10 2011-03-16 07:31:24

+0

不知道我是否同意,使用我列出的索引的原始查詢將在datadictionary和測試代碼上執行索引查找,這意味着數據庫引擎永遠不會觸及不需要的記錄。您將對兩個表格進行全索引掃描,觸及每個索引中的每個條目。對我來說,更少的磁盤活動幾乎總是更快。我感興趣的是哪個更快:) – 2011-03-16 07:50:24

+0

這取決於數據庫引擎MSSQL,MySQL,SQLite或Postgres。無論如何,使用連接在每個平臺上比子選擇更快。 – Pentium10 2011-03-16 07:55:44

1

如果dict.fid是一個獨特的密鑰(聽起來是如此),那麼你的查詢應相當於

WHERE co.vcode != (SELECT dict.vcode -- ... 

co.vcode和dict.vcode可能需要一個索引來加快速度。

這個答案不試圖給出比Pentium10更好的提示,更多的是阿里納斯。