Mysql
MySQL比較兩個大表的值
在 MySQL 5.7 上,我想從表 1 中獲取表 2 中不存在的記錄。
我正在使用這個非常慢(超過 2 分鐘)的簡單 LEFT JOIN 查詢,我不知道為什麼。
SELECT * FROM t1 LEFT JOIN t2 ON t1.name = t2.name WHERE t2.name is null
當我對查詢進行解釋時,我得到了這個結果
id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL index NULL NAME_UNIQUE 49 NULL 66387 100.00 Using index 1 SIMPLE t2 NULL index NULL NAEM_UNIQUE 37 NULL 2275410 10.00 Using where; Using index; Using join buffer (Block Nested Loop)
我在兩列“名稱”上都有一個唯一索引。
以下是表格定義:
CREATE TABLE `t1` ( `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `NAME` char(12) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `NAME_UNIQUE` (`NAME`) ) ENGINE=InnoDB AUTO_INCREMENT=50053 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; CREATE TABLE `t2` ( `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `NAME` char(12) DEFAULT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `NAME_UNIQUE` (`NAME`) ) ENGINE=InnoDB AUTO_INCREMENT=2049985 DEFAULT CHARSET=utf8mb4;
我認為這與使用“使用連接緩衝區(塊嵌套循環)”有關,但我試圖關閉但沒有任何效果:
SET SESSION optimizer_switch='block_nested_loop=off';
有什麼想法可以讓這個查詢表現得更好嗎?謝謝!
看起來兩個表上的 CHARSET 不匹配。嘗試在兩個表上設置相同的 CHARSET 和 COLLATION。
除了不同的字元集,左連接可能會做額外的工作,因為它計算來自 t1 的值,這些值可能與來自 t2 的許多行連接,並且由於 where 子句,無論如何都會被丟棄。嘗試 NOT IN 代替:
SELECT * FROM t1 WHERE t1.name NOT IN (SELECT t2.name FROM t2)