我有两个表,列表和产品。清单表有大约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" |
+----+-------------+-------+--------+---------------+---------+---------+---------------------+---------+----------------------------------------------+
答案 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)
请参阅链接的答案以查看更完整的代码示例。