MySQL JOIN非常缓慢,没有明显的原因

时间:2020-03-28 14:54:10

标签: mysql query-optimization mysql-8.0

MySQL 8.0.17版:

SELECT b.ColB
FROM Table2 b
JOIN Table1 a ON a.ColA = b.ColA
WHERE b.ColB = 1234 -- some number

使用JOIN,此查询大约需要2秒钟才能运行,而没有JOIN几乎是即时的。这只是一个最小的示例,实际情况需要WHERE条件才能覆盖多个值(例如WHERE b.ColB BETWEEN 1000 AND 2000),这需要非常长的时间...

表1的结构(为简洁起见,删除了不相关的列和索引):

CREATE TABLE `Table1` (
  `ColA` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`ColA`)
) ENGINE=InnoDB AUTO_INCREMENT=138221783 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

表2的结构(为简洁起见,删除了不相关的列和索引):

CREATE TABLE `Table2` (
  `ColA` int(11) NOT NULL,
  `ColB` int(11) NOT NULL,
  PRIMARY KEY (`ColA`,`ColB`),
  KEY `FK_Table2_Table1_idx` (`ColA`),
  KEY `FK_Table2_Table3_idx` (`ColB`),
  CONSTRAINT `FK_Table2_Table1` FOREIGN KEY (`ColA`) REFERENCES `Table1` (`ColA`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

这是此查询的说明的CSV:

id,select_type,table,partitions,type,possible_keys,key,key_len,ref,rows,filtered,Extra
1,SIMPLE,rc,NULL,ref,"PRIMARY,FK_Table2_Table1_idx,FK_Table2_Table3_idx",FK_Table2_Table3_idx,4,const,607,100.00,"Using index"
1,SIMPLE,r,NULL,eq_ref,PRIMARY,PRIMARY,4,Table2.ColA,1,100.00,"Using index"

运行此SELECT COUNT(*) FROM Table1的一些额外信息花费了8.735秒,返回了1947948。

运行此SELECT COUNT(*) FROM Table2花费了168.422秒,返回了19486319。

为什么JOIN导致查询运行如此缓慢?

2 个答案:

答案 0 :(得分:1)

如果唯一索引是PRIMARY KEY(colA, colB),而WHERE子句正在测试colB=constant,则没有可用的索引。

如果这是一个多对多映射表,则需要添加INDEX(colB, colA)以便有效地从B到A。

答案 1 :(得分:0)

要减少必须连接的行数,请尽可能减少行数。

为了你的快乐

使用

SELECT b.ColB
FROM (SELECT * FROM Table2 WHERE ColB = 1234) b
JOIN Table1 a ON a.ColA = b.ColA

您必须仅使用实际需要的列,而不是SELECT * FROM Table2。