如何选择tableB中存在但不存在于tableA中的记录(基本上就像tableB - tableA)?
我有以下表格:(每张表有100万条记录)
tableA
id int(11) NOT NULL PRIMARY KEY
name varchar(50)
sku varchar(10) index
description text
tableB
id int(11) NOT NULL PRIMARY KEY
stock int(11)
price int(11)
sku varchar(10) index
注意:sku已编入索引。
什么可以替代解决方案?
以下是我尝试的查询:
LEFT JOIN query:
SELECT a.sku FROM tableA a
LEFT JOIN tableB b
ON a.sku = b.sku
WHERE a.sku is NULL
NOT IN query:
SELECT * from tableB where sku NOT IN (SELECT sku from tableA)
答案 0 :(得分:0)
我认为最好的解决方案是left join
或:
select *
from tableB b
where not exists (select 1 from tableA where a.sku = b.sku);
not in
解决方案的问题是NULL
中的tableA
值将导致查询中未返回任何行。
为了提高性能,您需要tableA(sku)
上的索引:
create index tableA_sku on tableA(sku);
这将加快left join
和not exists
版本的速度。
答案 1 :(得分:0)
准备环境以复制问题:
DELIMITER $$
DROP PROCEDURE IF EXISTS `insertMe` $$
CREATE PROCEDURE insertMe()
BEGIN
DECLARE i BIGINT DEFAULT 2;
WHILE (i <= 1000000) DO
INSERT INTO tableA(id,NAME,sku,description) VALUES(i,CONCAT('name',i),CONCAT('sku',i),CONCAT('description',i));
IF(i%2=0) THEN
INSERT INTO tableB(id,stock,price,sku) VALUES(i,i%10,i%5,CONCAT('sku',i));
END IF;
SET i=i+1;
END WHILE;
/*
CALL insertMe();
*/
END $$
DELIMITER ;
CREATE INDEX idx_tableA ON tableA(sku);
CREATE INDEX idx_tableB ON tableB(sku);
您的要求的查询(使用左连接)已在我的测试环境中的1-2Sec中执行(2个具有1G RAM的虚拟CPU)。
@Gordon Linoff提到的左连接查询和查询没有任何问题,我建议按照GordonL的建议通过执行验证索引使用情况。
接下来,我怀疑MYSQL数据库中的陈旧表统计信息是否存在性能问题。请尝试以下脚本,然后查看查询的效果。
ANALYZE TABLE tableA;
ANALYZE TABLE tableB;
最后但同样重要的是,尝试备份/重新创建表及其索引以及上面的分析语句,然后查看查询的性能。它修复了行链和迁移的问题。