在SQL中,在连接时条件是否分组是否重要?

3

我通过SQL连接两个表并添加where子句。连接是通过where子句中的条件完成的。我想知道是否有区别,即where子句是否需要用括号分组来匹配连接子句。

举例来说:示例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(除了连接子句外,所有内容都已分组):

SELECT * FROM employees, vacation 
WHERE (employees.first_name = 'Maria' and vacation_start > 2017) 
    AND employees.employee_id = vacation.employee_id

示例3(连接子句是第一个where参数):
SELECT * FROM employees, vacation 
WHERE employees.employee_id = vacation.employee_id 
    AND (employees.first_name = 'Maria' and vacation_start > 2017)

我一直认为数据库会优化这种查询,但它们会吗?我主要使用MariaDB和SQLite。
3个回答

2

是的,它们是等价的。但是你应该使用显式连接而不是旧的 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)

我确实更喜欢显式连接,因为它可以清晰地表明表之间的关系。但是,这个查询是由一个编程库生成的,我无法强制使用选择-从-连接变体 :( - capfan
1
@capfan,JOIN语法不是变体——自1992年以来它就是标准语法。任何编程库不支持它都没有借口。 - Bill Karwin

1
  1. WHERE条件语句的顺序不重要,但是在JOIN操作中,表格的顺序是要考虑的。

  2. 如果将记录较少的表放在JOIN操作的左侧,会获得更好的性能表现。

  3. 关于WHERE条件语句,优化器会尽可能地将谓词下推以加快JOIN操作。这意味着它首先会对表格应用条件(例如 employees.first_name = 'Maria' and vacation_start > 2017),然后在过滤后的记录集上执行JOIN操作(例如 employees.employee_id = vacation.employee_id)。

    如果您查看查询的解释计划,就会更好地理解它。


1

在您的情况下,where子句中的分组仅对逻辑表达式有影响。例如;

(A and B and C)

A and (B and C)

是等价的。

但是

(A or B and C)

(A or B) and C

是不同的。

在您的示例中,所有查询都是相同的。如果您有非常大的数据,则可能会出现一些性能问题。如果没有问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接