查询不像程序那样执行。它们不是执行第 1 步然后执行第 2 步的过程。相反,它们是关于您想要什么结果的声明性陈述。在大多数现代 RDBMS 中,任何给定的查询都可以通过许多不同的查询计划来执行。通常,会创建不同的查询计划,然后评估哪个计划将运行得最快。在创建查询计划集时,它会考虑应该首先评估哪些条件,是否应该在评估条件之前或之后进行连接以及其他类似的事情,以试图找出哪些将被禁食(基于它对表的大小和关于在给定条件中包含多少百分比的表的猜测)。他们中的许多人还查看以前的结果,以便在他们的近似值错误时为未来的决策提供信息。
最有可能的是,在任何现代 RDBMS 中,这两个查询将生成相同的查询计划集,因此会做出相同的选择,从而导致对两个查询执行相同的查询计划。根据您使用的 RDBMS,通常有一些工具可用于查看为给定查询选择的特定查询计划,因此您可以使用它来绝对回答特定数据库上两个特定查询的问题。
现在,这么说,我应该注意,这并不等同于说“任何两个对相同数据总是产生相同答案的查询将总是花费相同的时间。” 编写非常糟糕的查询是可能的,主要是通过不必要的复杂性,并且不能保证查询规划器会意识到你做得过火了。它可能会捕获简单的案例。因此,例如:
SELECT * FROM student_tbl A, result_tbl B WHERE
A.student_name = B.student_name AND
A.student_name = 'xyz' AND
B.student_name = A.student_name
也可能会产生相同的查询计划。这也可能:
SELECT * FROM student_tbl A, result_tbl B WHERE
A.student_name = B.student_name AND
A.student_name = 'xyz' AND
B.student_name = 'xyz'
但是如果你做一些非常复杂的事情,比如
(SELECT * FROM student_tbl A, result_tbl B WHERE
A.student_name = B.student_name AND
A.student_name = 'xyz')
UNION
(SELECT * FROM student_tbl A, result_tbl B WHERE
A.student_name = B.student_name AND
B.student_name = 'xyz')
INTERSECT
(SELECT * FROM student_tbl A, result_tbl B WHERE
A.student_name = 'xyz')
它可能会运行更复杂的查询计划。(尽管如此,完全不必要的复杂查询将产生与其他两个相同的结果(假设没有 NULL))。
因此,优化器并非无所不知,但他们确实倾向于认识到 X AND Y 与 Y AND X 相同,并且 A=B AND B=C 与 A=C 和 A=B 相同,并进行相应调整对于那些情况。他们实际上进行了各种转换以尝试找到最佳查询,并且通常非常擅长找到它。可以覆盖查询计划器的决定,但只有当您确定有更好的查询方法并且数据更改不太可能改变时才应该这样做。