MYSQL执行流程的简单探讨

说到mysql的执行,就不得不说它的执行流程.而它的执行流程又分为标准执行流程和优化后的执行流程.

标准流程
标准流程是SQL执行的标准流程,几乎所有的SQL数据库都是以这个流程作为基础的.那么在联表的时候,他的流程是怎么样的呢?
这里会带入两个专业的名词,笛卡尔积,虚拟表(Virtual Table 简称VT);
笛卡尔积这个说明的篇幅太长,大家可以先google一下,这里就不说明了,而且一般有学过集合的同学,都知道这么一个东西
VT就是虚拟的表,在mysql处理某个问题的时候,它需要一个容器存放内容,那么这个容器就是VT.

以下是标准流程的举例说明
SELECT * FROM T1 INNER JOIN T2 ON T1.id = T2.t1_id WHERE T1.name = ‘name’ LIMIT 5;

这是一个很常见的SQL语句.那它在标准流程中是怎么执行的呢?
1.T1和T2进行笛卡尔积的计算,形成以个新的集合,放在一个VT内.我们称这个VT为VT1;
2.对VT1进行ON条件的处理,找出VT1中符合T1.id = T2.t1_id条件的记录,形成VT2;
3.对VT2进行WHERE字句处理,找出VT2中符合T1.name = ‘name’条件的记录,形成VT3;
4.对VT3进行LIMIT字句处理,取出前5条数据,形成VT4;
5.返回VT4;

这就是一个SQL的标准执行流程,由上面的流程可以看出,每两表相联的时候,都会先整理出一个笛卡尔集.这是非常消耗资源的.

这里我们再看一个子查询的处理过程.
SELECT * FROM (SELECT * FROM T1 WHERE T1.name = ‘name’) as TMP INNER JOIN T2 ON TMP.id = T2.t1_id LIMIT 5;

如果按照标准的执行流程.这里的处理流程是
1.对T1进行WHERE字句处理,得到一个临时表TMP;
2.TMP和T2进行笛卡尔积的计算,形成以个新的集合,形成VT1;
3.对VT1进行ON条件的处理,找出VT1中符合T1.id = T2.t1_id条件的记录,形成VT2;
4.对VT2进行WHERE字句处理,找出VT2中符合T1.name = ‘name’条件的记录,形成VT3;
5.对VT3进行LIMIT字句处理,取出前5条数据,形成VT4;
6.返回VT4;

对比之下,子查询比INNER JOIN查询多了一步的操作,就是先执行WHERE字句,过滤一遍T1,形成一个临时表.这样,使用TMP表和T2进行笛卡尔积计算的时候,因为TMP的数据比T1减少了很多,所以大大地提高了两表连接的效率.虽然说因为子查询而形成一个临时表,
增加了开销,但是却能很大程度地减少笛卡尔积的体积,这个牺牲是可接受的.

如果是这样的执行流程,子查询肯定会比INNER JOIN快.那为什么那么多人推荐INNER JOIN呢?终究其原因就是,MYSQL优化器.
在MYSQL的语句执行之前,都会经过优化器,优化器对SQL进行一系列的处理,编程它自己认为效率最高的方式(但也有失误的时候),然后再执行;

优化流程
以下是同一语句,经过MYSQL优化器处理之后的简述.MYSQL优化器做的事很多,这里只是简述.
SELECT * FROM T1 INNER JOIN T2 ON T1.id = T2.t1_id WHERE T1.name = ‘name’ LIMIT 5;

1.发现T1是主表,而且WHERE字句中使用的是T1中的name字段作为条件,所以优先排除T1.name != ‘name’的记录.形成VT1
2.TMP和T2进行笛卡尔积的计算,形成以个新的集合,形成VT2;
3.对VT2进行ON条件的处理,找出VT1中符合T1.id = T2.t1_id条件的记录,形成VT3;
4.对VT3进行WHERE字句处理,找出VT2中符合T1.name = ‘name’条件的记录,形成VT4;
5.对VT4进行LIMIT字句处理,取出前5条数据,形成VT5;
6.返回VT5;

优化器自行优先执行了WEHRE字句的内容,不用通过子查询来排除记录,这样既可以减少笛卡尔积的体积,同时也不会因为子查询而产生了一个临时表.
故得出,如果可以尽量使用联表查询的结论

题外拓展
很多时候,你自己认为的主表,并不是真正的主表.例如
SELECT * FROM T1 INNER JOIN T2 ON T1.id = T2.t1_id WHERE T2.name = ‘name’ LIMIT 5;

这条SQL中,用T2表中的name作为条件来查询,当优化器察觉到这个问题的时候,它就会选择T2作为主表,然后处理WHERE子句之后,再对T1进行联接
虽然出来的结果是一样的,但是他们的处理过程却不一定是你所想象的
当然,这个还跟WEHRE子句中所用到到的索引有关系,总之优化器会选择它认为最优的办法来执行.但是,优化器认为是最优的,事实上并不一定是,所以我们要知道它的执行流程和规律,让它在优化的时候,符合我们所想得.L

时间: 2024-09-20 05:44:26

MYSQL执行流程的简单探讨的相关文章

mysql启动错误1067简单解决方法

  解决方法 mysql数据库在运行时会在c盘windows文件夹下的temp文件夹里自动生成临时文件,这些文件不大,但是数量特别多,一个月下来很有可能就有几十万个文件了,导致mysql启动失败的罪魁祸首就是这些文件了,所以我们要做的就是删除这些文件,不过建议大家不要打开这个文件夹来删除,如果文件很多的话很容易出现打开很慢甚至卡死服务器的情况出现,所以在cmd窗口下用del命令来解决是最好的(如下) 经过以上操作,只要稍等一会里面的垃圾文件就都删除了,这时候只要重启你的mysql服务就可以了.为

通过一个模拟程序让你明白WCF大致的执行流程

在<通过一个模拟程序让你明白ASP.NET MVC是如何运行的>一文中我通过一个普通的ASP.NET Web程序模拟了ASP.NET MVC的执行流程,现在我们通过类似的原理创建一个用于模拟WCF服务端和客户端工作原理的模拟程序.[源代码从这里下载] 目录 一.基本的组件和执行流程 二.创建自定义HttpHandler实现对服务调用请求的处理 三.定义创建WCF组件的工厂 四.定义HttpModule映射WcfHandler 五.创建自定义的真实代理实现服务的调用 六.定义服务代理工厂 七.服

UBOOT添加命令的执行流程

BootLoader(引导装载程序)是嵌入式系统软件开发的第一个环节,它把操作系统和硬件平台衔接在一起,对于嵌入式系统的后续软件开发十分重要,在整个开发中也占有相当大的比例.U-BOOT是当前比较流行.功能强大的BootLoader,可以支持多种体系结构.LH7A400是Sharp公司生产的一款基于ARM922T内核的32位RISC芯片,本文详细介绍U-BOOT的功能.特点以及在LH7A400处理器上的移植过程.希望对大家有所帮助,更好的了解uboot命令的执行流程. 具体内容如下: U-Boo

vc++深入跟踪MFC程序的执行流程

在MFC程序设计的学习过程中最令人感到难受,甚至于有时会动摇学习者信心的就是一种对于程序的一切细节都没有控制权的感觉.这种感觉来源于学习者不知道一个MFC程序是如何运行起来的(即一个MFC程序的执行流程)和MFC程序的设计思想和机制,即使是写过Windows程序的学习者,也会感到非常迷惘并且无从下手.而这种感觉的出现会使大家认为自己离开了书本上的例子就无法设计编制程序.下面我就来说一说一个MFC具体是如何被执行的.在阅读本文之前,你要有一定的Windows程序设计基础,知道Windows程序的运

MySQL执行计划extra中的using index 和 using where using index 的区别

原文:MySQL执行计划extra中的using index 和 using where using index 的区别   本文出处:http://www.cnblogs.com/wy123/p/7366486.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他)   mysql执行计划中的extra列中表明了执行计划的每一步中的实现细节,其中包含了与索引相关的一些细节信息其中跟索引有关的using index

shell脚本实现监控shell脚本的执行流程及变量的值_linux shell

很多时候,我们都会写shell程序来完成一些不用重复造轮子的时刻,但是,又因为shell语句中也会有函数,也会有变量,在运行后到底执行了哪些相关的操作,就需要对具体执行过程中的变量等可变的因素的监控,那么我们下面就写个小小的shell例子,来完成这个对执行过程中条件语句中的变量的变化的监控和整个程序的执行流程的观察. shell程序代码: 复制代码 代码如下: #!/bin/bash function setlogfile {     if ! [ -z "$1" ]; then   

mysql执行计划介绍_Mysql

烂sql不仅直接影响sql的响应时间,更影响db的性能,导致其它正常的sql响应时间变长.如何写好sql,学会看执行计划至关重要.下面我简单讲讲mysql的执行计划,只列出了一些常见的情况,希望对大家有所帮助. 测试表结构: 复制代码 代码如下: CREATE TABLE `t1` (  `c1` int(11) NOT NULL DEFAULT '0',  `c2` varchar(128) DEFAULT NULL,  `c3` varchar(64) DEFAULT NULL,  `c4`

mysql主从复制(超简单)

mysql主从复制(超简单) 怎么安装mysql数据库,这里不说了,只说它的主从复制,步骤如下: 1.主从服务器分别作以下操作:1.1.版本一致1.2.初始化表,并在后台启动mysql1.3.修改root的密码 2.修改主服务器master: vi /etc/my.cnf [mysqld]log-bin=mysql-bin //[必须]启用二进制日志server-id=222 //[必须]服务器唯一ID,默认是1,一般取IP最后一段 3.修改从服务器slave: vi /etc/my.cnf [

《像计算机科学家一样思考Python》——3.7 执行流程

3.7 执行流程 为了保证函数的定义先于其首次调用执行,你需要知道程序中语句执行的顺序,即执行流程. 执行总是从程序的第一行开始.从上到下,按顺序,每次执行一条语句. 函数定义并不会改变程序的执行流程,但应注意函数体中的语句并不立即执行,而是等到函数被调用时执行. 函数调用可以看作程序执行流程中的一个迂回路径.遇到函数调用时,并不会直接继续执行下一条语句,而是跳到函数体的第一行,继续执行完函数体的所有语句,再跳回到原来离开的地方. 这样看似简单,但马上你会发现,函数体中可以调用其他函数.当程序流