SQL 如何处理 Oracle 11g 中的 where 子句?
How does SQL handle where clauses in Oracle 11g?
这只是一个简短的问题,目的是获得更多有关 SQL 工作原理的知识。
如果我有一个包含多个 where 条件的查询,例如第二个语句为假,查询中第二个语句之后的其余语句是否仍会被评估,或者 SQL 只是跳过在这一点上重新开始下一行?
示例:
SELECT * FROM MY_TABLE
WHERE NAME = "PETER"
AND LANGUAGE = "ENGLISH"
AND COUNTRY = "UK"
AND ENCRYPTION = "SHA-1";
我们的数据库是这样的:
| NAME | LANGUAGE | COUNTRY | ENCRYPTION |
PETER, ENGLISH, UK, SHA-1
PETER, FRENCH, SWITZERLAND, SHA-1
PETER, ENGLISH, USA, SHA-1
现在到了第二个条目时,查询会因为是"false"而在语言条件处停止吗,忽略后面的条件继续下一个条目还是会继续检查国家和加密?
您描述的是"short-circuiting"。事实上,大多数数据库在评估 where
子句时都会短路——如果它们一次评估每个子句一个比较。
但是,这没有什么不同。 SQL 专为大数据而设计。处理数据的开销是从永久存储读取和写入数据。相比之下,额外的计算时间通常是无关紧要的。并非总是如此——长字符串、JSON 字段、复杂的算术等会增加重要的处理时间。
如果你关心性能,你应该添加适当的索引。最适合您的查询的是 MY_TABLE(NAME, LANGUAGE, COUNTRY, ENCRYPTION)
(或以任何顺序以这四列开头的任何索引)。如果您关心性能,正确使用索引和 table 分区是您应该学习的内容。
这叫做 short circuiting
并且 SQL 服务器有它。
在 OR
表达式中,如果第一个条件为真,它不会检查其他条件,例如:
例如看到这个简单的查询,看到 (2 / @a = 1)
应该 return 错误
但未评估
DECLARE @a INT = 0
DECLARE @b INT = 10
SELECT 'name' AS Name
WHERE @b = 10 OR (2 / @a = 1)
在 AND
表达式中,如果第一个条件为假,它不会检查其他条件,例如:
例如看到这个简单的查询,看到 (2 / @a = 1)
应该 return 错误
但未评估
DECLARE @a INT = 0
DECLARE @b INT = 10
SELECT 'name' AS Name
WHERE @b = 14 and (2 / @a = 1)
在您的问题中,因为您使用的是 AND
,如果第一个条件为假,它不会检查其他条件
SQL 检查 WHERE 子句中的每个条件,直到找到第一个失败的条件,然后跳过该行。否则返回行。
SQL
是声明性的,即您的数据库系统可以选择以任何顺序评估 WHERE
子句。
此外,数据库系统尝试使用索引。例如,如果您在 COUNTRY
上声明了一个索引,您的数据库系统将使用此索引仅获取带有 COUNTRY='UK'
的元组,并且它只会评估这些元组的其余条件。 (为了简单起见,我假设这是这里唯一的索引)。
这个比短路求值强,因为在短路求值的时候,还是有求值顺序的。在 SQL
中,您编写语句的方式不会强制数据库系统以特定顺序评估您的条件。数据库系统将利用它来改进查询响应时间。
这只是一个简短的问题,目的是获得更多有关 SQL 工作原理的知识。
如果我有一个包含多个 where 条件的查询,例如第二个语句为假,查询中第二个语句之后的其余语句是否仍会被评估,或者 SQL 只是跳过在这一点上重新开始下一行?
示例:
SELECT * FROM MY_TABLE
WHERE NAME = "PETER"
AND LANGUAGE = "ENGLISH"
AND COUNTRY = "UK"
AND ENCRYPTION = "SHA-1";
我们的数据库是这样的:
| NAME | LANGUAGE | COUNTRY | ENCRYPTION |
PETER, ENGLISH, UK, SHA-1
PETER, FRENCH, SWITZERLAND, SHA-1
PETER, ENGLISH, USA, SHA-1
现在到了第二个条目时,查询会因为是"false"而在语言条件处停止吗,忽略后面的条件继续下一个条目还是会继续检查国家和加密?
您描述的是"short-circuiting"。事实上,大多数数据库在评估 where
子句时都会短路——如果它们一次评估每个子句一个比较。
但是,这没有什么不同。 SQL 专为大数据而设计。处理数据的开销是从永久存储读取和写入数据。相比之下,额外的计算时间通常是无关紧要的。并非总是如此——长字符串、JSON 字段、复杂的算术等会增加重要的处理时间。
如果你关心性能,你应该添加适当的索引。最适合您的查询的是 MY_TABLE(NAME, LANGUAGE, COUNTRY, ENCRYPTION)
(或以任何顺序以这四列开头的任何索引)。如果您关心性能,正确使用索引和 table 分区是您应该学习的内容。
这叫做 short circuiting
并且 SQL 服务器有它。
在 OR
表达式中,如果第一个条件为真,它不会检查其他条件,例如:
例如看到这个简单的查询,看到 (2 / @a = 1)
应该 return 错误
但未评估
DECLARE @a INT = 0
DECLARE @b INT = 10
SELECT 'name' AS Name
WHERE @b = 10 OR (2 / @a = 1)
在 AND
表达式中,如果第一个条件为假,它不会检查其他条件,例如:
例如看到这个简单的查询,看到 (2 / @a = 1)
应该 return 错误
但未评估
DECLARE @a INT = 0
DECLARE @b INT = 10
SELECT 'name' AS Name
WHERE @b = 14 and (2 / @a = 1)
在您的问题中,因为您使用的是 AND
,如果第一个条件为假,它不会检查其他条件
SQL 检查 WHERE 子句中的每个条件,直到找到第一个失败的条件,然后跳过该行。否则返回行。
SQL
是声明性的,即您的数据库系统可以选择以任何顺序评估 WHERE
子句。
此外,数据库系统尝试使用索引。例如,如果您在 COUNTRY
上声明了一个索引,您的数据库系统将使用此索引仅获取带有 COUNTRY='UK'
的元组,并且它只会评估这些元组的其余条件。 (为了简单起见,我假设这是这里唯一的索引)。
这个比短路求值强,因为在短路求值的时候,还是有求值顺序的。在 SQL
中,您编写语句的方式不会强制数据库系统以特定顺序评估您的条件。数据库系统将利用它来改进查询响应时间。