Mysql

“NOT IN”的快速替代方案

  • July 28, 2015

我有一個表 A 有一個名為 id 的欄位,它是該表的主鍵。我還有一個名為 B 的表,其中還有一個名為 id 的欄位作為主鍵。

現在我想從表 A 中獲取所有行,其中 id 值不作為任何表 B id 欄位值中的值存在。

我的第一個查詢如下所示:

SELECT a.id FROM a WHERE a.id NOT IN (SELECT DISTINCT b.id FROM b)

然後我建構一個看起來像這樣的查詢來提高速度:

SELECT a.id FROM a LEFT JOIN b ON a.id = b.id WHERE b.id IS NULL

現在我在表 A 中有 600k 行,在表 B 中有 400k 行,事情變得非常緩慢。有沒有更好的查詢來執行這種操作,或者是否有更好的方法來解決問題?任何提示或指示?

你必須做的是增加join_buffer_size。什麼是 join_buffer_size ?

用於普通索引掃描、範圍索引掃描和不使用索引並因此執行全表掃描的連接的緩衝區的最小大小。通常,獲得快速連接的最佳方法是添加索引。***當無法添加索引時,增加 join_buffer_size 的值以獲得更快的完全連接。***為兩個表之間的每個完全連接分配一個連接緩衝區。對於未使用索引的多個表之間的複雜連接,可能需要多個連接緩衝區。

我突出顯示了這句話,因為您的查詢很簡單。您正在對一個整數進行連接,我假設該整數已在兩個表中建立索引。如果表中的 idb未編入索引,請盡快編入索引。

我建議將join_buffer_size提高到 4M。

您可以在會話中更改join_buffer_size並重新執行查詢

SET join_buffer_size = 1024 * 1024 * 4;
SELECT a.id FROM a LEFT JOIN b ON a.id = b.id WHERE b.id IS NULL;

試一試 !!!

引用自:https://dba.stackexchange.com/questions/108268