消除MySQL中的子查询

时间:2016-05-20 00:11:16

标签: mysql

我在MySQL中有两个表。

CREATE TABLE `TABLE_A` (
  `id_a` varchar(50) NOT NULL ,
  `ref` varchar(50) NOT NULL,
  `colA` varchar(50) NOT NULL,
            :
  PRIMARY KEY (`id_a`),
  KEY `INDEX_A1` (`ref`)
  KEY `INDEX_A2` (`colA`)
) ENGINE=InnoDB


CREATE TABLE `TABLE_B` (
  `id_b` int(11) NOT NULL AUTO_INCREMENT,
  `ref` varchar(50) NOT NULL,
  `status` int(11) NOT NULL,
             :
  PRIMARY KEY (`ib_b`),
  KEY `INDEX_B1` (`ref`),
) ENGINE=InnoDB

我对这些表有一个查询,如下所示。但是这个查询很慢。

SELECT T1.* FROM TABLE_A AS T1 
LEFT JOIN (SELECT ref,MAX(status) as status FROM TABLE_B GROUP BY ref )
AS T2 ON T1.ref = T2.ref
WHERE T2.status = ? AND T1.colA = ?

我在这个SQL上尝试explain,结果如下。

+----+-------------+------------+--------+--------------+----------+---------+--------+-------+-------------+
| id | select_type | table      | type   | possible_key | key      | key_len | ref    | rows  | Extra       |
+----+-------------+------------+--------+--------------+----------+---------+--------+-------+-------------+
|  1 | PRIMARY     | T1         | ref    | INDEX_A2     | INDEX_A2 | 152     | const  |   136 | Using where |
|  1 | PRIMARY     | <derived2> | ALL    | NULL         | NULL     | NULL    | NULL   | 29400 | Using where |
|  2 | DERIVED     | TABLE_B    | index  | NULL         | INDEX_B1 | 152     | NULL   | 36223 | Using where |
+----+-------------+------------+--------+--------------+----------+---------+--------+-------+-------------+

我认为我必须删除子查询以改进我的查询。

如果没有子查询,我怎么能做同样的事情?或者我还有其他改进方法吗?

1 个答案:

答案 0 :(得分:0)

试试这个:

select 
  t1.*
from table_a as t1
  inner join table_b as t2
    on t1.ref = t2.ref
  left outer join table_b as t3
    on t3.ref = t2.ref
    and t3.status > t2.status
where t3.status is null;

This很好地解释了上述原因应该如何运作。