2009-12-25 57 views
2

我正在執行一個查詢,該查詢正在查找不在另一個表中的值。例如:MySQL查詢優化

SELECT id FROM table1 WHERE id NOT IN (SELECT id FROM table2); 

兩個表都有大約100萬行,但只有幾百行與結果集中返回的值不匹配。查詢大約需要35秒。在查詢中顯示配置文件顯示mysql大部分時間處於「準備」狀態。關於如何優化這種狀態或「準備」期間實際發生的情況的任何想法?

兩個表中的id值都被編入索引,並且具有相同的類型和大小。

查詢的整個輪廓是:

+--------------------------------+----------+ 
| Status       | Duration | 
+--------------------------------+----------+ 
| (initialization)    | 0  | 
| checking query cache for query | 0  | 
| Opening tables     | 0.13  | 
| System lock     | 0  | 
| Table lock      | 0  | 
| init       | 0.01  | 
| optimizing      | 0  | 
| statistics      | 0  | 
| preparing      | 0  | 
| executing      | 0  | 
| Sending data     | 0  | 
| optimizing      | 0  | 
| statistics      | 0  | 
| preparing      | 34.83 | 
| end       | 0  | 
| query end      | 0  | 
| freeing items     | 0  | 
| closing tables     | 0  | 
| logging slow query    | 0  | 
+--------------------------------+----------+ 

任何提示讚賞。

謝謝。

回答

3

我會離開連接table2 id id爲null。 這會給你一個更快的數據返回。

select 
    a.id 
from 
    table1 a 
    left join table2 b on a.id = b.id and b.id is null 
+0

高興你chnaged是正確的加入到左! – 2009-12-25 02:33:54

+0

如果這是和WHERE b.id爲空? – 2009-12-25 02:49:49

+0

最好在where子句中指定它;但優化者應該制定相同的計劃。 – 2009-12-25 02:52:03

1
SELECT id FROM table1 
LEFT JOIN table2 ON table1.id = table2.id 
WHERE table2.id IS NULL; 
+0

查詢仍然需要大約30秒,但對於「show profile ;」大部分時間都在「發送數據」中。那只是mysql運行查詢所需的時間,還是我能做些什麼來加快速度? – 2009-12-25 02:46:43

+0

它將取決於你定義了什麼索引...... – 2009-12-25 02:52:44

2

沒有什麼優化 - NOT IN在MySQL產生一個等效的查詢計劃LEFT JOIN/IS NULL。 Quote:

但是,這三種方法生成三個不同的計劃,由三個不同的代碼段執行。執行EXISTS謂詞的代碼比執行index_subquery和LEFT JOIN的代碼效率低30%左右,並優化爲使用Not exists方法。

這就是爲什麼在MySQL中搜索缺失值的最佳方法是使用LEFT JOIN/IS NULL或NOT IN而不是NOT EXISTS。

欲瞭解更多信息,請參閱NOT IN vs. NOT EXISTS vs. LEFT JOIN/IS NULL: MySQL

+0

當然應該對table2.id進行索引以產生等效查詢。但是從它的名字(這聽起來像一個'PK')和事實上,查詢需要'350000'秒的'1,000,000'行,我們可以得出結論,它被索引。 – Quassnoi 2009-12-25 12:20:34