对于简单的用途,MySQL 几乎不可避免地会以相同的方式执行它们,因此这是一种偏好和可读性的方式(这是一个很大的争论主题)。
然而,对于更复杂的查询,特别OUTER JOIN
是具有可能成为磁盘和 io 绑定的 s 的聚合查询 - 不使用带有 OUTER JOIN 查询的 WHERE 子句可能会产生性能和不可见的影响。
运行 8 分钟或 0.8 秒的查询之间的差异最终可能取决于WHERE
子句,特别是当它与索引有关时(MySQL 如何使用索引):WHERE
子句是为查询优化器提供所需信息的核心部分完成它的工作并告诉引擎如何以最有效的方式执行查询。
从MySQL 如何使用 WHERE 优化查询:
“本节讨论可用于处理 WHERE 子句的优化......通过尝试所有可能性来找到用于连接表的最佳连接组合。如果 ORDER BY 和 GROUP BY 子句中的所有列都来自同一个表,则该表是加入时优先考虑。”
对于连接中的每个表,构造一个更简单的 WHERE 以获得对表的快速 WHERE 评估并尽快跳过行
一些例子:
全表扫描(类型 = ALL),Using where
在 EXTRA中没有
[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id AND cr.role = cr2.role AND cr.util = 1000
[Err] Out of memory
用于where
优化结果,带有索引 ( Using where
, Using index
):
[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id
WHERE cr.role = cr2.role
AND cr.util = 1000
515661 rows in set (0.124s)
**** ON/WHERE 的组合 - 相同的结果 - ******** 中的相同EXPLAIN
计划
[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id
AND cr.role = cr2.role
WHERE cr.util = 1000
515661 rows in set (0.121s)
MySQL 通常足够聪明,可以计算出像上面这样的简单查询,并且会以类似的方式执行它们,但在某些情况下它不会。
外连接查询性能:
由于 LEFT JOIN 和 RIGHT JOIN 都是 OUTER JOIN(此处进行了深入的回顾),因此出现了笛卡尔积的问题,必须避免表扫描,以便尽可能快地消除查询不需要的行尽可能。
WHERE
, 索引和查询优化器一起使用可以完全消除笛卡尔积所带来的问题,当仔细使用聚合函数,如,,AVERAGE
等等。通过用户适当的索引和 WHERE 的使用,运行时间减少了几个数量级。条款。GROUP BY
SUM
DISTINCT
最后
同样,对于大多数查询,查询优化器将以相同的方式执行这些 - 使其成为一种首选方式,但是当查询优化变得重要时,WHERE
它是一个非常重要的工具。通过将索引 col 指定为附加的 ON..AND ON 子句,我在某些情况下看到了一些性能提升,INNER JOIN
但我无法告诉您原因。