欢迎来到天天文库
浏览记录
ID:55709850
大小:58.50 KB
页数:8页
时间:2020-05-26
《从实例中浅析如何优化SQL语句.doc》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、从实例中浅析如何优化SQL语句王忠强'龙森2(1.四川师范大学成都学院办公室,四川成都611745:2.成都布络软件公司,四川成都210009)在现代软件编程以及网络编程中,数据库的应用使编程进入了新的时代。尤其是sql以后以及orale等中大型商业数据库的开发使用,正在为开发中大型软件及网络应用程序奠定了基础。在数据库开发中,sql查询语句的优劣直接决定了查询数据的效率的高低,而sql语句的优化问题,就进一步显现出它的重要性及实用性。下面,我们将以一些实例举例说明如何优化SQL语句。(一):逻辑查询的各个阶段在查询中逻辑查询和物理查询有着本质的区别,SQL不同于其它编程的最明显的特
2、征就是处理代码的顺序,虽然总是最先写SELECT但是几乎总在最后执行,那到底是怎么一个执行顺序呢下面,我们采用ItZikBen-Gan、LuborKollar>DejanSarka所著的(SqlServer2005技术内幕:T-SQL查询》{附注}一书中的例子予以说明。作者给出了如下的sql查询语句执行顺序(8)select(9)distinct(11)(1)from(3)join(2)on(4)where3、_condition>(3)groupby(4)with(cube4、rollup}(5)having(having_condition)(10)orderby从这个顺序中我们不难发现,所有的查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。具体每步执行内容如下:第一步:首先对from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表vtl第二步:接下来便是应用on筛选器,on中的逻辑表达式将应用到vtl中的各个行,筛选出满足on逻辑表达式的5、行,生成虚拟表vt2第三步:如果是outerjoin那么这一步就将添加外部行,leftouterjion就把左表在第二步中过滤的添加进来,如果是rightouterjoin那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表vt3第四步:如果from子句中的表数目多余两个表,那么就将vt3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表vt3o第五步:应用where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表vt4,在这有个重要的细节值得注意,对于包含outerjoin子句的查询,就有一个让人感到困惑的问题,到底6、在on筛选器还是用where筛选器指定逻辑表达式呢?on和where的最大区别在于,如果在on应用逻辑表达式那么在第三步outerjoin中还可以把移除的行再次添加回来,而where的移除的最终的。举个简单的例子,有一个学生表(班级,姓名)和一个成绩表(姓名,成绩),我现在需要返回一个x班级的全体同学的成绩,但是这个班级有几个学生缺考,也就是说在成绩表中没有记录。为了得到我们预期的结果我们就需要在on子句指定学生和成绩表的关系(学生.姓名=成绩.姓名)那么我们是否发现在执行第二步的时候,对于没有参加考试的学生记录就不会出现在vt2中,因为他们被on的逻辑表达式过滤掉了,但是我们用le7、ftouterjoin就可以把左表(学生)中没有参加考试的学生找回来,因为我们想返回的是x班级的所有学生,如果在on中应用学生.班级=又的话,那么在leftouterjoin中就会将不会把x班级的学生的所有记录找回来,所以只能在where筛选器中应用学生.班级=乂应为它的过滤是最终的。第六步:groupby子句将中的唯一的值组合成为一组,得到虚拟表vt5。如果应用了gro叩by,那么后面的所有步骤都只能得到的vt5的列或者是聚合函数(count>sum>avg等)。原因在于最终的结果集中只为每个组包含一行。这一点请牢记。第七步:应用cube或者8、roll叩选项,为vt5生成超组,生成vt6.第八步:应用having筛选器,生成vt7。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。第九步:处理select列表。将vt7中的在select中出现的列筛选出来。生成vt8.第十步:应用distinct子句,vt8中移除相同的行,生成vt9。事实上如果应用了gro叩by子句那么distinct是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以
3、_condition>(3)groupby(4)with(cube
4、rollup}(5)having(having_condition)(10)orderby从这个顺序中我们不难发现,所有的查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。具体每步执行内容如下:第一步:首先对from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表vtl第二步:接下来便是应用on筛选器,on中的逻辑表达式将应用到vtl中的各个行,筛选出满足on逻辑表达式的
5、行,生成虚拟表vt2第三步:如果是outerjoin那么这一步就将添加外部行,leftouterjion就把左表在第二步中过滤的添加进来,如果是rightouterjoin那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表vt3第四步:如果from子句中的表数目多余两个表,那么就将vt3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表vt3o第五步:应用where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表vt4,在这有个重要的细节值得注意,对于包含outerjoin子句的查询,就有一个让人感到困惑的问题,到底
6、在on筛选器还是用where筛选器指定逻辑表达式呢?on和where的最大区别在于,如果在on应用逻辑表达式那么在第三步outerjoin中还可以把移除的行再次添加回来,而where的移除的最终的。举个简单的例子,有一个学生表(班级,姓名)和一个成绩表(姓名,成绩),我现在需要返回一个x班级的全体同学的成绩,但是这个班级有几个学生缺考,也就是说在成绩表中没有记录。为了得到我们预期的结果我们就需要在on子句指定学生和成绩表的关系(学生.姓名=成绩.姓名)那么我们是否发现在执行第二步的时候,对于没有参加考试的学生记录就不会出现在vt2中,因为他们被on的逻辑表达式过滤掉了,但是我们用le
7、ftouterjoin就可以把左表(学生)中没有参加考试的学生找回来,因为我们想返回的是x班级的所有学生,如果在on中应用学生.班级=又的话,那么在leftouterjoin中就会将不会把x班级的学生的所有记录找回来,所以只能在where筛选器中应用学生.班级=乂应为它的过滤是最终的。第六步:groupby子句将中的唯一的值组合成为一组,得到虚拟表vt5。如果应用了gro叩by,那么后面的所有步骤都只能得到的vt5的列或者是聚合函数(count>sum>avg等)。原因在于最终的结果集中只为每个组包含一行。这一点请牢记。第七步:应用cube或者
8、roll叩选项,为vt5生成超组,生成vt6.第八步:应用having筛选器,生成vt7。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。第九步:处理select列表。将vt7中的在select中出现的列筛选出来。生成vt8.第十步:应用distinct子句,vt8中移除相同的行,生成vt9。事实上如果应用了gro叩by子句那么distinct是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以
此文档下载收益归作者所有