我不知道,下面是我瞎猜的。先改成如下: select * from tb where (a=x1 and b=y1) or (a=x2 and b=y2 ) select * from tb where (a=x1 or a=x2) and (b=y1 or b=y2 )查询结果显然不一定相同,前者相当与x1y1+x2y2, 后者相当于(x1+x2)(y1+y2)>=x1y1+x2y2关于效率,作一些假设吧: 1〕单一条件的查询记录都是1/4 2〕单一条件的查询时间都为t 3)查询条件分解时间忽略 4)或操作的时间忽略 5)查询时间与记录数成正比前者的查询时间分析: 1)首先查询条件是或 2)查询条件是与 3〔查询时间为t,记录数为1/4 4〕因为是与,后面查询就是在前面查询结果中再查询,因此时间是0.25t 5〔类似分析后面的查询时间 6〕所以总的查询时间应该是 t+0.25t+t+0.25t=2.5t类似的可以分析第二种查询 1〔与, 2〕前面的查询时间是t+t=2t,记录数目为0。5 3〔后面也是2t记录数目,与的查询时间是0。5 4〕与的查询时间是0。5×0。5t=0。25t 5〔总查询时间是 2t+2t+0.25t=4.5t结论是:后面一种查询耗时多,因为它遍历了数据表4次,而前者只有两次。一切都是瞎猜的,没有看过书或者资料,一想要看它们就头大:)
实际上这是SQL SERVER 的查询优化的问题!针对不同的查询结构有不同的性能开销!在SQL SERVER中有个内部进程叫查询优化器,它的功能主要是优化查询,判断一个查询设计的优劣可以通过下面的一些工具来实现: 1、对CPU的执行时间的统计:SET STATISTISC TIME ON 2、对物理盘的读,对内存中的数据页的读:SET STATISTICS IO ON 其中物理读是在硬盘中的数据页调到内存中的页数,逻辑读是内存中扫描的页数! 3、通过SET SHOWPLAN_ALL ON 来查看在查询运行时的性能代价! 以上三项设置都是在查询分析器里进行设置!
select * from tb where (a=x1 and b=y1) or (a=x2 and b=y2 )
select * from tb where (a=x1 or a=x2) and (b=y1 or b=y2 )查询结果显然不一定相同,前者相当与x1y1+x2y2,
后者相当于(x1+x2)(y1+y2)>=x1y1+x2y2关于效率,作一些假设吧:
1〕单一条件的查询记录都是1/4
2〕单一条件的查询时间都为t
3)查询条件分解时间忽略
4)或操作的时间忽略
5)查询时间与记录数成正比前者的查询时间分析:
1)首先查询条件是或
2)查询条件是与
3〔查询时间为t,记录数为1/4
4〕因为是与,后面查询就是在前面查询结果中再查询,因此时间是0.25t
5〔类似分析后面的查询时间
6〕所以总的查询时间应该是
t+0.25t+t+0.25t=2.5t类似的可以分析第二种查询
1〔与,
2〕前面的查询时间是t+t=2t,记录数目为0。5
3〔后面也是2t记录数目,与的查询时间是0。5
4〕与的查询时间是0。5×0。5t=0。25t
5〔总查询时间是
2t+2t+0.25t=4.5t结论是:后面一种查询耗时多,因为它遍历了数据表4次,而前者只有两次。一切都是瞎猜的,没有看过书或者资料,一想要看它们就头大:)
也许我说得不够清楚,那两个语句只是举例。我记得当初我学FOXBASE时我问起大型数据库,老师一时兴起,顺便给我们讲过结构化查询语言常用语句的语法分析器是怎样分析、工作的,好象常用语句的基本是相同的。下面摘自其他文章,仅仅是抛砖引玉,只言片语很不全面,这也是我提出这个问题的原因——很希望有个全面一点的基本、大概的了解。
1.“where条件中的'in'在逻辑上相当于'or',所以语法分析器会将in ('0','1')转化为id_no ='0' or id_no='1'来执行。我们期望它会根据每个or子句分别查找,再将结果相加,这样可以利用id_no上的索引;但实际上(根据showplan),它却采用了"OR策略",即先取出满足每个or子句的行,存入临时数据库的工作表中,再建立唯一索引以去掉重复行,最后从这个临时表中计算结果。因此,实际过程没有利用id_no上索引,并且完成时间还要受tempdb数据库性能的影响。”
2.“所谓优化即where子句利用了索引,不可优化即发生了表扫描或额外开销。 where子句中对列的任何操作结果都是在SQL运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被SQL优化器优化,使用索引,避免表搜索,
---- 1.任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。---- 2.in、or子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引。---- 3.要善于使用存储过程,它使SQL变得更加灵活和高效。”
不同意关于IN的说法,你说的是以前优化器不是很好的情况,其实现在的SQL SERVER 2000的优化器能很好的比较算法的费用,一般 IN ("0","1")这样的语句能利用索引,速度不慢,而 IN +子句 就一定不能用索引。
我是从Microsoft 数据库培训教程中看到的。
1、对CPU的执行时间的统计:SET STATISTISC TIME ON
2、对物理盘的读,对内存中的数据页的读:SET STATISTICS IO ON 其中物理读是在硬盘中的数据页调到内存中的页数,逻辑读是内存中扫描的页数!
3、通过SET SHOWPLAN_ALL ON 来查看在查询运行时的性能代价!
以上三项设置都是在查询分析器里进行设置!