SQL查询处理顺序不一致

时间:2016-10-23 15:10:24

标签: sql oracle oracle11g

有两个表productsproduct_types,两者都有以下行:

products

enter image description here

product_types

enter image description here

执行以下查询:

SELECT p.name, pt.name
FROM products p, product_types pt
WHERE p.product_type_id = 1;

产生以下结果:

enter image description here

但执行此查询:

SELECT p.name, pt.name
FROM products p, product_types pt
WHERE p.product_type_id = pt.product_type_id
OR p.product_type_id = 1;

产生以下结果:

enter image description here

通常情况下,SQL解释器以一个表开头并跨越另一个表,这是什么规则?在第一个查询中,它以products表开始并跨越product_types,但在第二个查询中,它以product_types表开始并跨越products表(如从订单中可以看出)。为什么它不一致,通常,我希望第二个查询的结果是这样的:

enter image description here

为什么?它会选择随机开始的表还是什么?

注意:不介意查询,它可能没有多大意义,我只对结果的顺序感兴趣。

2 个答案:

答案 0 :(得分:4)

您完全误解了SQL的工作原理。

SQL查询表示来自关系数据库的数据处理的结果。他们代表所采取的步骤。 SQL查询基本上分三个步骤处理:

  1. 解析查询。
  2. 解析后的结果会生成优化的执行计划。
  3. SQL引擎执行结果。
  4. 你说:

      

    通常情况下,SQL解释器以一个表开头并跨越另一个表,这是什么规则?

    这远非事实。

    事实是,SQL表和结果集代表无序集。他们没有订购。也许你应该重复50次。不同顺序的两个结果集是相同的。

    SQL 支持ORDER BY子句,因为排序很重要。这是您按指定顺序获得结果的方式。

    另外,我强烈建议您停止在FROM子句中使用逗号。这是表示连接的一种非常古老的方式。正确的方法是将显式JOIN关键字与ON子句中的条件一起使用 - 这已成为SQL标准的一部分已超过20年。

答案 1 :(得分:3)

  

它是选择随机开始的表还是什么?

它可能看似随机,但事实并非如此。只是查询优化器可以自由地考虑执行查询的不同方式,并选择它认为将以最佳方式返回预期结果(由查询定义)的执行计划。

即使对查询定义稍有改动也可能导致优化器考虑使用不同的执行计划以提高效率。即使多次执行相同的查询,也可能在不同的时间选择不同的执行计划,例如,所涉及的不同表中的数据分布发生了变化(这只是众多可能原因中的一种)。

事实上,它可以选择在给定情况下最佳的执行计划,这将影响返回的行的顺序。这完全在查询优化器可以执行的操作的权限范围内,因为 您没有通过在查询中包含ORDER BY子句来请求显式结果顺序。 您可以保证结果一致排序的唯一方法是通过ORDER BY子句明确请求该订单。不要让别人告诉你,他们在撒谎。