这2个sql查询在所有方面是否相同(例如估计和实际执行计划)?

问题描述:

查询1)== 2)在估计查询计划和实际计划方面? (可统计在这里影响实际的计划,永远不会消失?)这2个sql查询在所有方面是否相同(例如估计和实际执行计划)?

声明@cat INT - 从中​​国

输入参数...

1)

select * 
from A as a 
    join B as b 
    on b.id = a.id 
    on b.cat = @cat 
    join C as c 
    on c.fid = b.fid 
    on c.cat = @cat 
    where a.cat = @cat 

2)

select * 
from A as a 
    join B as b 
    on b.id = a.id 
    on b.cat = a.cat 
    join C as c 
    on c.fid = b.fid 
    on c.cat = b.cat 
    where a.cat = @cat 

在我看来,这些应该在逻辑上是等同的,执行计划应该始终是相同的gardless表中的实际差异。并且在连接或其中添加更多条件或添加更多表来加入不应该改变这一点。

有没有这种情况是不正确的?

+1

要知道的唯一方法是要求你的特定SQL引擎告诉你。 – bmargulies 2010-01-15 16:36:10

优化器可能受到a.cat,b.cat或c.cat中是否有可用索引的影响 - 以及该索引是否也包含相关的id或fid列。将简单的WHERE子句谓词推送到表级操作可能足够智能。它也可能受到表格统计数据的影响。 (如果参数的值刚好在C中出现一次,那么开始处理C可能比开始处理A要有效得多;或者从B开始可能更有效;或者它可能更有效从A开始。在执行语句之前,优化器不知道参数的值可能也可能没有关系,而不是在准备好时能够看到它。)

因此,在评论中暗示,没有关于您正在使用的系统(包括模式等)的更多信息而无法做出明确的声明。

好消息是结果内容应该是一样的 - 执行计划不能保证。


我注意到,大多数SQL系统将需要一个关键字为每个加盟:

select * 
from A as a 
    join B as b 
    on b.id = a.id 
    AND b.cat = @cat 
    join C as c 
    on c.fid = b.fid 
    AND c.cat = @cat 
    where a.cat = @cat 

XERION问:

鉴于执行计划可能会有所不同,但其时尚查询是“更好”的。哪里更好定义为:

  1. 更有可能被优化以提供更好的计划(或不太可能混淆SQL优化器)。
  2. 更符合SQL约定。

它依赖于DBMS及其优化器;有这方面的不可替代的经验,但要记住,因为什么是凭经验在一个时间点来确定可能是在另一点错误时间:

  1. 数据集已经改变大小
  2. 数据集有不同的统计分布现在
  3. 优化可能已经改变
  4. 还可有不同的指标

有很多方法可以做到的加入,和它(ST生病)取决于可用的索引。我可能会写:

SELECT * 
    FROM A JOIN B ON b.id = a.id AND b.cat = a.cat 
     JOIN C ON c.fid = b.fid AND c.cat = b.cat 
WHERE a.cat = @cat 
    AND b.cat = @cat 
    AND c.cat = @cat 

这里的逻辑是,有可能是在A(ID,猫)指数和B(ID,猫),以及关于B(FID,CAT)和C( fid,cat),因此优化器可以充分利用这些索引。 WHERE子句包含两个冗余项,但让优化器知道需要什么,并明确告诉它它本身可能不会推导出的内容。如果你对优化器的质量有信心(并且已经检查了它产生的查询计划),那么你可以消除WHERE子句中三个条件中的两个。

如果将参数放在ON子句中,优化程序可能没有像使用索引那样更好地使用索引 - 再次,您必须试验以确定优化程序的行为方式。

最后,正如已经暗示的那样,表中的索引集非常重要,并且确保DBMS需要的任何统计信息都是最新的,这一点非常重要。还要记住,如果表最初很小,那么优化器可能会从表变大时选择一个不同的查询计划 - 在合理的级别进行测试也是如此。除非生产表只包含几十行,否则不要对仅有几十行的表进行性能测试。

+0

够公平的。考虑到执行计划可能不同,哪种查询方式“更好”。哪里更好定义为:1)更有可能被优化以提供更好的计划(或不太可能混淆SQL优化器)。 2)更符合SQL约定。对不起,如果这个问题似乎微不足道,我是相当新的SQL。 – Xerion 2010-01-15 19:46:16