sql执行机制
详见: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执行机制的更多相关文章
- 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 ...
- [转载]循规蹈矩:快速读懂SQL执行计划的套路与工具
作者介绍 梁敬彬,福富研究院副理事长.公司唯一四星级内训师,国内一线知名数据库专家,在数据库优化和培训领域有着丰富的经验.多次应邀担任国内外数据库大会的演讲嘉宾,在业界有着广泛的影响力.著有多本畅销书 ...
- Oracle sql执行计划解析
Oracle sql执行计划解析 https://blog.csdn.net/xybelieve1990/article/details/50562963 Oracle优化器 Oracle的优化器共有 ...
- 0708关于理解mysql SQL执行顺序
转自 http://www.jellythink.com/archives/924,博客比价清晰 我理解上文的是SQL执行顺序 总体方案.当你加入索引了以后,其实他的执行计划是有细微的变化,比方说刚开 ...
- MySQL架构与SQL执行流程
MySQL架构设计 下面是一张MySQL的架构图: 上方各个组件的含义如下: Connectors 指的是不同语言中与SQL的交互 Management Serveices & Utiliti ...
- 一条简单的 SQL 执行超过1000ms,纳尼?
作者:VipAugus https://juejin.im/post/5ce906a3e51d455a2f2201dc MySQL对我说"Too young, too naive!" ...
- 自己动手写SQL执行引擎
自己动手写SQL执行引擎 前言 在阅读了大量关于数据库的资料后,笔者情不自禁产生了一个造数据库轮子的想法.来验证一下自己对于数据库底层原理的掌握是否牢靠.在笔者的github中给这个database起 ...
- 大型面试现场:一条update sql执行都经历什么?
导读 Hi,大家好!我是白日梦!本文是MySQL专题的第 24 篇. 今天我要跟你分享的MySQL话题是:"从一条update sql执行都经历什么开始,发散开一系列的问题,看看你能抗到第几 ...
- oracle sql 执行计划分析
转自http://itindex.net/detail/45962-oracle-sql-%E8%AE%A1%E5%88%92 一.首先创建表 SQL> show user USER is &q ...
随机推荐
- NodeJS之queryString
前面的话 无论是前端还是后端,经常出现的应用场景是URL中参数的处理.nodeJS的queryString模块提供了一些处理 query strings 的工具.本文将详细介绍nodeJS中的quer ...
- vue.js移动端app实战2:首页
貌似有部分人要求写的更详细,这里多写一点vuel-cli基础的配置 什么是vue-cli? 官方的解释是:A simple CLI for scaffolding Vue.js projects, 简 ...
- [js高手之路] es6系列教程 - 不定参数与展开运算符(...)
三个点(...)在es6中,有两个含义: 用在形参中, 表示传递给他的参数集合, 类似于arguments, 叫不定参数. 语法格式: 在形参面前加三个点( ... ) 用在数组前面,可以把数组的值 ...
- 1.nodejs介绍
1.什么是nodejs 1.(javascript跑在机器端,服务端)Javascript on the machine 2.(跑在谷歌v8引擎上)A runtime for Google Chrom ...
- MacOS下安装gdb、mgo
安装gdb:http://blog.panks.me/posts/2013/11/install-gdb-on-os-x-mavericks-from-source/ 注意最后两步: killall ...
- 嵌入式GPIO接口及操作(一)
GPIO意思就是通用输入输出,一些引脚可以通过他们输出高低电平,或者通过它们读入引脚的状态.对GPIO的操作是对所有硬件的操作最基本的技能.一.通过寄存器来操作GPIO引脚,一个引脚可以用于输入.输出 ...
- python细碎语法点
在系统入门python有的是没有遇到,有的是学过了缺乏使用没有记住,就开篇随笔记录这些基础的语法点,随时更新. with...as... 也就是说with是一个控制流语句,跟if/for/while/ ...
- 对接第三方平台JAVA接口问题推送和解决
前言 本节所讲为实际项目中与第三方对接出现的问题最后还是靠老大解决了问题以此作为备忘录,本篇分为三小节,一小节解析Java加密接口数据,二小节解析XML文件需注意问题,最后一节则是请求Java Soa ...
- U3D操作游戏对象
游戏对象:所有出现在场景中的实体都是游戏对象. 一.创建游戏对象 创建游戏对象有两种方式:一是通过在unity中创建模型,而是通过脚本动态创建游戏对象.通过脚本动态创建的灵活性较高,重点也在于通过脚本 ...
- mysql 5.7.19 安装
下载 官方下载地址,要注意的是要下载的是 MySQL Community Server.根据系统选择相应压缩包,这个是 win 下安装.选择 Zip Archive 安装 将下载好的压缩包解压到想要安 ...