在SQL中,是否在连接的情况下对条件进行分组是否重要?

时间:2017-08-15 18:49:59

标签: mysql sql performance sqlite

我通过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子句首先是参数):

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

我一直认为数据库会优化这种查询。 但他们呢?我主要使用MariaDB和SQLite。

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

  1. 条件无关紧要的顺序,但是您在连接中写入的表的顺序很重要。
  2. 如果你保持表格在连接左侧的记录较少会提供更好的表现。
  3. 关于WHERE条件,优化程序将始终按下谓词以更快地进行连接操作。这意味着它将首先应用表格上的条件(employees.first_name ='Maria'和vacation_start&gt; 2017),然后在过滤的记录集上执行join(employees.employee_id = vacation.employee_id)。

    如果您查看查询的解释计划,您会更加了解它。

答案 2 :(得分:1)

where 子句中的分组首先仅对您的案例中的逻辑表达式有意义。例如;

  

(A和B和C)

  

A和(B和C)

是等价的。

但是

  

(A或B和C)

  

(A或B)和C

是不同的。

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