请问在一个查询里表连接的顺序对查询的性能是否有影响

请问在一个查询里表连接的顺序对查询的性能是否有影响?

楼主wxbfly(背着黄金的飞鸟)2002-12-11 11:38:45 在 MS-SQL Server / 基础类 提问

如果有影响,我想问连接时的顺序是从左到右还是从右到左?   
    
  如:   a   inner   join   b   on   condition1   left   outer   join   c   on   condition2     
          inner   join   d   on   condition3   
  其执行连接的顺序是什么?如果各个表的大小不一样,那么应该遵循什么规则才能达到最快速度?   
    
  不好意思,在书上找不到,就上来问啦。另外,where子句里的各个条件语句放置顺序是否对查询有影响?   
 问题点数:100、回复次数:21Top

1 楼CCEO(CSDN的CEO)回复于 2002-12-11 11:43:04 得分 20

sql   server的自动优化机制使得这个次序是没有意义的,除非你自己指定了油画选项。   
 Top

2 楼CrazyFor(冬眠的鼹鼠)回复于 2002-12-11 11:45:06 得分 0

还是找书吧,清楚点   
    
  简单说一下,   
    
  A和B表   
  A   left   outer   join   B   =   B   right   outer   join   A   
    
  A   left   outer   join   B   适合A和B的一对多关系,即A的一条记录对应B的多条记录,如“-->”   如引号中的箭头,结果集中只包括A表中有的记录。Right   outer   join   如“<--”   
  A   full   outet   join   B     如“<-->”   
    
 Top

3 楼Chiff(~o~)回复于 2002-12-11 11:45:27 得分 30

where子句里的各个条件语句放置顺序是否对查询有影响?   
    
  据我观察没有。因为不管你怎样放,mssql最后都会按他的规则排顺序。   
  据我所知,所有常量逻辑总是会排在最前面。比方说:   
  where   1=1   and   列a='a'   
  sql在查询时总是会把1=1之类的放在前面。Top

4 楼wxbfly(背着黄金的飞鸟)回复于 2002-12-11 11:51:16 得分 0

没有连接顺序?好象不对吧,我记得哪里说可以用括号来改变连接的顺序的。请各位明示。   
    
  to   CCEO()   :   
  请问油画机制是做什么用的?Top

5 楼Chiff(~o~)回复于 2002-12-11 11:53:40 得分 0

(油画)优化机制。Top

6 楼microd(重构一切)回复于 2002-12-11 11:55:08 得分 0

不用说,肯定有Top

7 楼Chiff(~o~)回复于 2002-12-11 11:58:26 得分 0

关于条件顺序判断,很容易测试的:   
  拿个除以零的条件放在条件列表里面。   
    
 Top

8 楼microd(重构一切)回复于 2002-12-11 12:00:45 得分 10

Where   后面的条件有影响,在同等条件,把记录多条件的放在最后面,因为Where   语句总是从最后面的语句开始执行,这样会减少过滤时间(也就是执行时间呢!)。Top

9 楼wxbfly(背着黄金的飞鸟)回复于 2002-12-11 12:07:45 得分 0

ok,我可以测where后条件的执行顺序。   
    
  to   microd(做人真累):   
  关于你说的从后到前的执行顺序你有没有测过,是否真的是这样?Top

10 楼mylovexs(不了塵)回复于 2002-12-11 12:35:27 得分 10

有影響,sql查詢優化器根據where循序採用索引,除非指定索引Top

11 楼Chiff(~o~)回复于 2002-12-11 12:37:00 得分 0

microd(做人真累):   
  “因为Where   语句总是从最后面的语句开始执行”   
  你试过吗?何以见得?Top

12 楼Chiff(~o~)回复于 2002-12-11 13:14:58 得分 0

关于条件执行的顺序,让我们来做一个测试!   
    
  create   table   test(id   int)   
  insert   into   test   values(1)   
  insert   into   test   values(2)   
  ------------------------------------------   
  select   *   from   test   where   1/0=1   or   1=1   
  --1   
  --2   
  select   *   from   test   where   1/0=1   or   id   in(1,2)   
  --遇到零除错误   
  select   *   from   test   where   1/0=1   and   id   =   3   
  --遇到零除错误   
  ------------------------------------------   
  select   *   from   test   where   id/0=id   or   id=id   
  --遇到零除错误   
    
  select   *   from   test   where   id=id   or   id/0=id   
  --1   
  --2   
  -------------------------------------------   
  select   *   from   test   where   1/0=1   or   id   =   1   
  --遇到零除错误   
  -------------------------------------------   
  select   *   from   test   where   id/0   =   1   or   id   =   id     
  --遇到零除错误   
    
  select   *   from   test   where   id   =   id   or   id   /   0   =   1   
  --1   
  --2   
  -------------------------------------------   
  select   *   from   test   where   id/0   =1   or   1=1   or   id/0   =   4   or   1/0=1   or   id=id/0   
  --1   
  --2   
  select   *   from   test   where   id/0   =1   and   1=2   and   id/0   =   4   and   1/0=1   and   id=id/0   
  --没有结果,也没有报错   
  -------------------------------------------   
    
  至少可以看出:   
  sql在执行条件语句的时候是将条件分级别匹配的,级别最高的是:   
    
  常量与常量的比较   
    
  而且级别分得非常细,所以我也分析不出确切的机制。   
    
  只有在级别完全相同的时候,才是从左至右或从右至左来匹配。   
  不对之处请大家指正。Top

13 楼Chiff(~o~)回复于 2002-12-11 13:52:56 得分 0

大家来讨论一下。Top

14 楼xystarch(Cyan)回复于 2002-12-11 14:14:54 得分 0

我觉得对这个问题的分析需要对SQL语言的底层结构和它所基于的数学理论进行讨论,比如关系代数与集合演算.   
  但是SQLServer内置的查询优化器会改变实际查询的方式,在QA里面看到的   
  Executing   Plan并不符合我们实际的sql语句   
  好像有个开关   
  set   queryOptima=off(具体是什么我忘了)   
  将优化器关掉后就可以看到连接顺序和条件顺序对于性能优化的影响了.Top

15 楼wxbfly(背着黄金的飞鸟)回复于 2002-12-11 14:19:15 得分 0

谢谢Chiff(~o~)   的关心。   
    
  我想讨论对大家都会有好处,我可以加分,请各位高手继续。Top

16 楼xystarch(Cyan)回复于 2002-12-11 14:21:01 得分 30

SQL   SERVER   的查询引擎是基于开销的查询引擎.   
  基于开销的查询优化器在备选计划中选择应答   SQL   查询的计划。选择是基于对执行特殊计划的开销估算(I/O   操作数、CPU   秒数,等等)而作出的。它通过记录表或索引中记录的数目和构成的统计数字估算这些开销。与基于语法的查询优化器不同,它不依赖于查询的确切语法或查询中的子句顺序。   
 Top

17 楼Chiff(~o~)回复于 2002-12-11 14:26:41 得分 0

xystarch说得有道理。Top

18 楼Chiff(~o~)回复于 2002-12-11 14:27:31 得分 0

问题是,mssql是怎样判断开销的呢?Top

19 楼zxdragon(zxdragon)回复于 2002-12-11 14:28:03 得分 0

实际上ON后面的条件内容也很重要。   
  通常在表连接时,一般采用   
  A   LEFT   JOIN   B   ON   A.id=B.id   
  如果可能写成   
  A   LEFT   JOIN   B   ON   A.id=B.id   AND   A.Name=B.Name   AND   A.Date=B.Date   ...   
  虽然   A.id=B.id   就一定决定   A.Name=B.Name   AND   A.Date=B.Date   
  但是还是劝你写的繁一点,这样在你联接N多个表或数据量较大时,你的查询时间会少很多。   
  血的教训呀~~~Top

20 楼xystarch(Cyan)回复于 2002-12-11 14:39:49 得分 0

http://www.microsoft.com/china/technet/sql/Technote/dat411.asp   
    
  我们所写出的sql语句是一个查询计划,是抽象数学演算的实现,最值得信赖的优化还是要根据关系代数与集合演算来做   
  我的导师告诉我说:将你的sql语句转化成数学演算来分析怎么实现优化!   
  但是实际情况中我们又不得不考虑表中数据量对于性能的影响   
  基于开销和基于语法这两种模型的结合才是最理想的.   
  但是这个mssql是怎么实现的?的确是个问题(我想这个可能是mssql的核心所在吧).Top

21 楼xystarch(Cyan)回复于 2002-12-11 14:49:16 得分 0

我找到那条语句了   
    
  SET   FORCEPLAN   ON   
    
  将会强制查询基于语法而不是开销.

你可能感兴趣的:(数据结构,sql,SQL Server,Microsoft,asp)