在连接的情况下,条件是不是在 SQL 中分组是不是重要?
Posted
技术标签:
【中文标题】在连接的情况下,条件是不是在 SQL 中分组是不是重要?【英文标题】:Does it matter in SQL whether conditions are grouped in case of a join?在连接的情况下,条件是否在 SQL 中分组是否重要? 【发布时间】:2017-08-15 18:49:59 【问题描述】:我确实通过 SQL 连接了 2 个表并添加了 where 子句。连接由 where 子句中的条件完成。 我想知道 where 子句期望 join 子句是否按括号分组是否会有所不同。
用例子来问:例子1等同于例子2和例子3吗?
示例 1(无分组):
SELECT * FROM employees, vacation
WHERE employees.first_name = 'Maria' and vacation_start > 2017
AND employees.employee_id = vacation.employee_id
示例 2(除了 join 子句之外的所有内容都被分组):
SELECT * FROM employees, vacation
WHERE (employees.first_name = 'Maria' and vacation_start > 2017)
AND employees.employee_id = vacation.employee_id
示例 3(join 子句是第一个 where 参数):
SELECT * FROM employees, vacation
WHERE employees.employee_id = vacation.employee_id
AND (employees.first_name = 'Maria' and vacation_start > 2017)
我一直认为数据库会优化这种查询。 但是他们呢?我主要使用 MariaDB 和 SQLite。
【问题讨论】:
【参考方案1】:是的,它们是等价的。但是你应该使用显式连接而不是旧的WHERE
语法:
SELECT *
FROM employees
JOIN vacation
ON employees.employee_id = vacation.employee_id
WHERE employees.first_name = 'Maria' and vacation_start > 2017;
简单的逻辑:
-- AND has associative property
cond1 AND cond2 AND cond3
<=>
(cond1 AND cond2) AND cond3
<=>
cond1 AND (cond2 AND cond3)
【讨论】:
我确实更喜欢显式连接,因为它使表关系清晰。但是,查询是编程库的结果,我无法强制执行 select-from-join 变体:( @capfan,JOIN
语法不是变体——它是自 1992 年以来的标准语法。任何编程库都没有理由不支持它。【参考方案2】:
where 条件的顺序无关紧要,但您在连接中编写的表的顺序很重要。
如果将记录较少的表保留在连接左侧,则性能会更好。
关于您的 WHERE 条件,优化器将始终下推谓词以使连接操作更快。这意味着它将首先对表应用条件(employees.first_name = 'Maria' and holiday_start > 2017),然后在过滤的记录集上执行 join(employees.employee_id = holiday.employee_id)。
如果您检查查询的解释计划,您会更了解它。
【讨论】:
【参考方案3】:where 子句中的分组首先仅对您的案例中的逻辑表达式很重要。比如;
(A和B和C)
和
A 和(B 和 C)
是等价的。
但是
(A 或 B 和 C)
和
(A 或 B)和 C
不同。
在您的示例中,所有查询都相同。如果您有非常大的数据,您的分组选择可能会出现一些性能问题。如果不是没有问题。
【讨论】:
以上是关于在连接的情况下,条件是不是在 SQL 中分组是不是重要?的主要内容,如果未能解决你的问题,请参考以下文章
默认情况下,条件使用“内连接”而不是“左连接”方法使我的查询工作不是我计划的方式
如何在不使用 SQL 中的多个连接条件的情况下获取同一行中的所有值?