详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp38

sql执行机制

1.对于普通的sql语句只有where条件的执行机制

    首先我们要了解一下SQL语句的执行过程。SELECT字段FROM表名WHERE条件表达式那它们是按什么顺序执行呢?

分析器会先看语句的第一个词,当它发现第一个词是SELECT关键字的时候,它会跳到FROM关键字,然后通过FROM关键字找到表名并把表装入内存。接着是找WHERE关键字,如果找不到则返回到SELECT找字段解析,如果找到WHERE,则分析其中的条件,完成后再回到SELECT分析字段。最后形成一张我们要的虚表。其它的先不说了,只说WHERE。WHERE关键字后面的是条件表达式。

    如果学过C语言等编程语言就会知道,条件表达式计算完成后,会有一个返回值,即非0或0,非0即为真(true),0即为假(false)。同理WHERE后面的条件也有一个返回值,真或假,来确定接下来执不执行SELECT。

例:SELECT*FROM STUDENT WHERE SNO='1';分析器先找到关键字SELECT,    然后跳到FROM关键字将STUDENT表导入内存,并通过指针p1找到第一条记录,接着找到WHERE关键字计算它的条件表达式,如果为真那么把这条记录装到一个虚表当中,p1再指向下一条记录。如果为假那么p1直接指向下一条记录,而不进行其它操作。一直检索完整个表,关把虚表返回给用户。

2.对于嵌套的sql语句

再说EXISTS谓词,EXISTS谓词也是条件表达式的一部分。当然它也有一个返回值(true或false)。例:SELECT Sname FROM Student WHERE EXISTS(SELECT*FROM SC WHERE SC.Sno=Student.Sno AND SC.Cno='1');这是一个SQL语句的嵌套使用,但和上面说的SQL语句的执行过程也是相同的。嵌套的意思也就是说当分析主SQL语句(外面的那个SELECT,我们权且先这么叫它)到WHERE关键字的时候,又进入了另一个SQL语句中。那么也就是说,分析器先找到表Student并装入内存,一个指针(例如p1)指向Student表中的第一条记录。然后进入WHERE里分析里面的SQL语句,再把SC表装入内存,另一个指针(例如p2)指向SC表中的第一条记录,分析WHERE后面的条件表达式,依次进行分析,最后分析出一个虚表2,也就变成SELECT Sname FROM Student WHERE EXISTS虚表2如果虚表为空表,EXISTS虚表2也就为false,不返回到SELECT,而p1指向下一条记录。

3.示列分析

select distinct(a.s_cid),SUM(N_JE),count(a.S_CID) from zw_yingyez a  inner join KG_BiaoKaXX b on a.S_CID=b.S_CID

where a.I_XiaoZhang=0

group by a.S_CID

having SUM(N_JE)>100

order by a.S_CID

执行顺序:

(8)  SELECT  (9) DISTINCT (11) <TOP_specification> <select_list> 

(1)  FROM <left_table>  

(3) <join_type> JOIN <right_table> 

(2) ON <join_condition> 

(4) WHERE <where_condition> 

(5) GROUP BY <group_by_list> 

(6) WITH {CUBE | ROLLUP} 

(7) HAVING <having_condition> 

(10) ORDER BY <order_by_list>

以上每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只有最后一步生成的表才会会给调用者。如果没有在查询中指定某一个子句,将跳过相应的步骤。

  逻辑查询处理阶段简介:

  1、 FROM:对FROM子句中的前两个表执行笛卡尔积(交叉联接),生成虚拟表VT1。

  2、 ON:对VT1应用ON筛选器,只有那些使为真才被插入到TV2。

  3、 OUTER (JOIN):如果指定了OUTER JOIN(相对于CROSS JOIN或INNER JOIN),保留表中未找到匹配的行将作为外部行添加到VT2,生成TV3。如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表位置。

  4、 WHERE:对TV3应用WHERE筛选器,只有使为true的行才插入TV4。

  5、 GROUP BY:按GROUP BY子句中的列列表对TV4中的行进行分组,生成TV5。

  6、 CUTE|ROLLUP:把超组插入VT5,生成VT6。

  7、 HAVING:对VT6应用HAVING筛选器,只有使为true的组插入到VT7。

  8、 SELECT:处理SELECT列表,产生VT8。

  9、 DISTINCT:将重复的行从VT8中删除,产品VT9。

  10、ORDER BY:将VT9中的行按ORDER BY子句中的列列表顺序,生成一个游标(VC10)。

11、TOP:从VC10的开始处选择指定数量或比例的行,生成表TV11,并返回给调用者。

总结 :

执行顺序

FROM

JOIN

WHERE

GROUP

HAVING

SELECT

ORDER

SQL是按照这个顺序来的

Sql语句优化

1.WHERE后面的条件顺序影响

WHERE子句后面的条件顺序对大数据量表的查询会产生直接的影响,如

Select * from zl_yhjbqk where dy_dj = '1KV以下' and xh_bz=1

Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1KV以下'

以上两个SQL中dy_dj(电压等级)及xh_bz(销户标志)两个字段都没进行索引,所以执行的时候都是全表扫描,如果dy_dj = '1KV以下'条件在记录集内比率为99%,而xh_bz=1的比率只为0.5%,在进行第一条SQL的时候99%条记录都进行dy_dj及xh_bz的比较,而在进行第二条SQL的时候0.5%条记录都进行dy_dj及xh_bz的比较,以此可以得出第二条SQL的CPU占用率明显比第一条低。所以尽量将范围小的条件放在前面。

2.使用in时,在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,这样可以减少判断的次数

3. exists 和 in 的效率 当两个表大小差不多的时候,效率差不多,但是当一个表大一个表小的时候,子查询表大的用exists,子查询表小的用in

in是把外表和内表作hash连接,而exists 是对外表作loop循环,每次loop循环再对内表进行查询。

列于表A(小表),表B(大表)

select * from A where cc in(select cc from B) 效率低

select * from A where where exists (select cc from B where cc=A.cc) 效率高

4.效率对比

createtime between '2011-7-4 0:00:00' AND '2011-8-4 23:59:59'

convert(varchar(10),createtime,112) between '20110704' and '20110804'

sql执行机制的更多相关文章

  1. Sql server在使用sp_executesql @sql执行文本sql时,报错: Could not find database ID 16, name '16'. The database may be offline. Wait a few minutes and try again.

    最近在公司项目中使用exec sp_executesql @sql执行一段文本sql的时候老是报错: Could not find database ID 16, name '16'. The dat ...

  2. [转载]循规蹈矩:快速读懂SQL执行计划的套路与工具

    作者介绍 梁敬彬,福富研究院副理事长.公司唯一四星级内训师,国内一线知名数据库专家,在数据库优化和培训领域有着丰富的经验.多次应邀担任国内外数据库大会的演讲嘉宾,在业界有着广泛的影响力.著有多本畅销书 ...

  3. Oracle sql执行计划解析

    Oracle sql执行计划解析 https://blog.csdn.net/xybelieve1990/article/details/50562963 Oracle优化器 Oracle的优化器共有 ...

  4. 0708关于理解mysql SQL执行顺序

    转自 http://www.jellythink.com/archives/924,博客比价清晰 我理解上文的是SQL执行顺序 总体方案.当你加入索引了以后,其实他的执行计划是有细微的变化,比方说刚开 ...

  5. MySQL架构与SQL执行流程

    MySQL架构设计 下面是一张MySQL的架构图: 上方各个组件的含义如下: Connectors 指的是不同语言中与SQL的交互 Management Serveices & Utiliti ...

  6. 一条简单的 SQL 执行超过1000ms,纳尼?

    作者:VipAugus https://juejin.im/post/5ce906a3e51d455a2f2201dc MySQL对我说"Too young, too naive!" ...

  7. 自己动手写SQL执行引擎

    自己动手写SQL执行引擎 前言 在阅读了大量关于数据库的资料后,笔者情不自禁产生了一个造数据库轮子的想法.来验证一下自己对于数据库底层原理的掌握是否牢靠.在笔者的github中给这个database起 ...

  8. 大型面试现场:一条update sql执行都经历什么?

    导读 Hi,大家好!我是白日梦!本文是MySQL专题的第 24 篇. 今天我要跟你分享的MySQL话题是:"从一条update sql执行都经历什么开始,发散开一系列的问题,看看你能抗到第几 ...

  9. oracle sql 执行计划分析

    转自http://itindex.net/detail/45962-oracle-sql-%E8%AE%A1%E5%88%92 一.首先创建表 SQL> show user USER is &q ...

随机推荐

  1. python函数(5):迭代器和生成器

    迭代器和生成器是函数中的一大重点,务必掌握,何为迭代?何为迭代器? 预习: 处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕 一.迭代器 for i in 50: pr ...

  2. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  3. git for windows+TortoiseGit客户端的使用二

    通常都是使用git协议方式来连接服务器,然后使用https方式的连接方法,是如何设置的: 先登录github服务器,获取远程服务器仓库: 在本地创建一个存放仓库的目录,然后使用tortoiseGit客 ...

  4. POJ-1915 Knight Moves (BFS)

    Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 26952   Accepted: 12721 De ...

  5. js判断移动终端(手机浏览器)

    方法1: <script type="text/javascript">         var browser = {             versions: f ...

  6. let const 下篇

    1.不存在变量提升 在之前的js代码中,声明一个变量或者是函数,会存在变量提升的现象,也就是说变量可以在声明之前使用,值为undefined: es5: console.log(a); //undef ...

  7. js prototype属性,类似.net扩展方法

    prototype 属性使您有能力向对象添加属性和方法. 类似.net扩展方法 定义: String.prototype.toWeekName = function () { var newDate ...

  8. Jenkins 环境搭建

    本文为jenkins入手教程,全文分为 jenkins安装.系统管理(配置全局安全.全局工具配置.管理插件).创建项目(同时创建证书),管理视图,jenkins 客户端,执行构建.查看任务历史 一.j ...

  9. Brackets 1.8 开源+免费的Web前端网页文本编辑工具

    Brackets 1.8 开源+免费的Web网页文本编辑工具   -------------->> ---------------------- A modern, open source ...

  10. 通俗语言解释内外网IP与端口映射

    IP:分为外网IP和内网IP 也就是我们说的外网IP属于实体IP 实体IP,它是独一无二的,在网络的世界里,每一部计算机的都有他的位置,一个 IP 就好似一个门牌!例如,你要去百度的网站的话,就要去『 ...