Mysql

MySQL比較兩個大表的值

  • June 17, 2019

在 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)

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