MySQL LEFT JOIN优化

时间:2013-10-25 00:38:04

标签: mysql

我有以下查询

  • A有1 000 000行
  • B,C,D各有150 000行
  • E有50 000行

查询本身似乎需要大约50秒才能完成。它通常包含一个WHERE子句,因为它正在搜索数据库中的所有可能数据。有什么方法可以改进吗?

SELECT A.one, A.two, A.three
FROM A
LEFT JOIN B ON ( A.id = B.id ) 
LEFT JOIN C ON ( A.id = C.d ) 
LEFT JOIN D ON ( A.id = D.id ) 
LEFT JOIN E ON ( A.name =  E.name 
AND  E.date <= A.date ) 
ORDER BY A.id ASC

解释查询:

+----+-------------+-------+--------+---------------+----------+---------+-----------+--------+-------------+
| id | select_type | table | type   | possible_keys | key      | key_len | ref       | rows   | Extra       |
+----+-------------+-------+--------+---------------+----------+---------+-----------+--------+-------------+
|  1 | SIMPLE      | A     | index  | NULL          | PRIMARY  | 17      | NULL      | 357752 |             |
|  1 | SIMPLE      | B     | eq_ref | PRIMARY       | PRIMARY  | 17      | db.A.id   |      1 | Using index |
|  1 | SIMPLE      | C     | eq_ref | PRIMARY       | PRIMARY  | 17      | db.A.id   |      1 | Using index |
|  1 | SIMPLE      | D     | eq_ref | PRIMARY       | PRIMARY  | 17      | db.A.id   |      1 | Using index |
|  1 | SIMPLE      | E     | ref    | Name,Date     | Name     | 62      | db.A.name |      1 |             |
+----+-------------+-------+--------+---------------+----------+---------+-----------+--------+-------------+

1 个答案:

答案 0 :(得分:1)

我建议使用双列索引替换E - NameDate上的索引,因为对于最后一次加入,您实际上是在选择来自E的{​​{1}}和name符合条件。因为date是eq,所以它应该是索引中的第一个。

name

这将使连接选择完全使用索引。

另外 - 我认为这是一个示例查询,但您似乎没有使用ALTER TABLE `E` ADD INDEX idx_join_optimise (`name`,`date`) BC这可能会降低它的速度。

如果您提到的D子句使用其他表中的值,我建议根据条件将它们更改为WHERE。(如果您发布了一些示例,它会有所帮助你正在做什么)