简体   繁体   中英

MySQL JOIN very slow for no apparent reason

MySQL version 8.0.17:

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

With the JOIN , this query takes about 2 seconds to run, without the JOIN it is almost instant. This is just a minimal example, the actual case requires the WHERE condition to cover multiple values (eg WHERE b.ColB BETWEEN 1000 AND 2000 ) - which takes a very very long time...

Structure of Table1 (irrelevant columns and indexes removed for brevity):

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

Structure of Table2 (irrelevant columns and indexes removed for brevity):

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;

This is the CSV of the explain on this query:

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"

Some extra info running this SELECT COUNT(*) FROM Table1 took 8.735 seconds and returned 1947948.

Running this SELECT COUNT(*) FROM Table2 took 168.422 seconds and returned 19486319.

Why is the JOIN causing the query to run so very slowly?

If the only index is PRIMARY KEY(colA, colB) and the WHERE clause is testing colB=constant , then there is no usable index.

If this is a many-to-many mapping table you need to add INDEX(colB, colA) to allow for efficiently going from B to A.

To reduce the number of Rows that have to be joined reduce the number of rows as much as you can.

For your qiery

Use

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

Instead of the SELECT * FROM Table2, you must use only the column that you actually need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM