LEFT JOIN上的MySql Long查询时间

时间:2015-11-13 20:15:21

标签: php mysql

我有两个表,列表和产品。清单表有大约1.2M的记录,产品表有大约600K的记录。当我在列表上运行以下查询时,结果返回56.6毫秒。

SELECT    l.field_name
FROM      Listing l
WHERE     l.deletedAt IS NULL
GROUP BY  l.field_name HAVING COUNT(l.field_name) > 1

当我添加LEFT JOIN时,返回结果需要将近50秒。

SELECT    l.field_name, p.name
FROM      Listing l
LEFT JOIN Product p
 ON       l.product_id = p.id
WHERE     l.deletedAt IS NULL
GROUP BY  l.field_name HAVING COUNT(l.field_name) > 1
ORDER BY  l.field_name

在Listings表中可能存在field_name的重复项,因此可能是HAVING语句。

如何优化此查询以更快地返回结果。感谢

解释输出

+----+-------------+-------+--------+---------------+---------+---------+---------------------+---------+----------------------------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref                 | rows    | Extra                                        |
+----+-------------+-------+--------+---------------+---------+---------+---------------------+---------+----------------------------------------------+
|  1 | SIMPLE      | l     | ALL    | field_name    | NULL    | NULL    | NULL                | 1022146 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | p     | eq_ref | PRIMARY       | PRIMARY | 4       | dbName.l.product_id | 1       | Using index"                                 |
+----+-------------+-------+--------+---------------+---------+---------+---------------------+---------+----------------------------------------------+

1 个答案:

答案 0 :(得分:0)

此处的速度基本上取决于 JOIN 每个 一侧的记录数。

看起来您正在搜索标记为“未删除”的记录,并且“具有field_name”。还有一个GROUP BY如果你试图在JOIN后尝试这样做会减慢速度,看起来你也可以在加入之前执行GROUP BY。

在这种情况下,您应首先查询所有“过滤”,并以正确的顺序开始,并将该较小的记录集与另一个表连接,再次要求排序结果。

每个DBMS都有一个稍微不同的SQL查询来实现这一点。在高级DBMS中,您可以使用WITH ... AS ... SELECT ...(“with”子句)语法。

使用MySQL,你必须想出另一种表达同样事物的方法。这里有一些如何做的样本:

MySQL的伪代码应该是这样的:

SELECT
  a.name, b.description
FROM
  (subset of "a" table, order by id [group by could be here, too])
  JOIN
  (subset of "b" table, order by id)

请参阅链接的答案以查看更完整的代码示例。