vlambda博客
学习文章列表

MySQL一条查询语句的执行过程

    

日常开发中我们难以避免与数据接触,那么数据库就是不可或缺的一部分了,因为需要数据库去存储数据,程序也需要通过数据库去操作数据。这里我以mysql为例,首先来看一个SQL语句

select * from table_name where id=1

这是一个简单的查询语句,用来查询表中满足条件的数据。那么这个SQL语句的执行过程是怎么样的呢?一起来看看吧

    首先,需要与数据建立连接吧,就比如从密码箱中取东西,我们第一步是要输入正确的密码,数据库就类似于密码箱,只不过它存储数据。客户端发起请求到数据库连接器,然后连接器会验证用户名和密码,只有用户名和密码正确才能继续,如果错误会提示 “Access denied for user”。建立连接之后,如果长时间不进行操作,连接会断开,客户端在此请求就会重新连接。

数据库连接分为两种:

短连接:每次执行完很少的几次查询就断开连接,下次想查询时,就要重新建立一个

长连接:如果客户端持续有请求,那就一直使用同一个连接

每次请求都重新建立连接的话,在时间上是一种消耗,所以建议使用长连接。

凡事有利必有弊,长时间连接会对资源造成一定的浪费,因为只有连接断开时才会释放资源。针对这种情况的处理措施有两种:

  • 定时断开长连接

  • mysql5.7版本及以上通过执行 mysql_reset_connection 来重新初始化连接资源,这个过程不需要重新连接和权限验证

    连接上数据库之后,就是对SQL语句进行分析,接着上面密码箱的例子,打开密码箱接下来需要分析我们需要干什么,是往里面放东西,还是取东西?分析SQL就需要分析器,第一步是词法分析,通过“select”知道这是查询操作(从密码箱取东西),然后“table_name”确定操作的表(东西在密码箱那一层),最后分析where条件(从密码箱取啥)。第二步就是语法分析了,曾经经历过英语摧残的小伙伴们肯定知道,英语语法(主语、谓语、宾语),这里也是对SQL语法的一种检测,如果错误会提示“You hava an error in your SQL syntax”。

    经过分析之后,确定了SQL要干什么,但是怎么做效率最高呢?密码箱里要取出的东西和其他物件在一起,怎么才能最快的拿出来呢?这里就要考虑到索引、多表联合的情况,针对这些情况做优化,这就是优化器的职责。

    一系列的准备工作都做完了,接下来就是执行了,也就是从密码箱把东西拿出来。执行器会调用数据库引擎接口去取表的第一行数据判断id是否等于1,然后取下一行,直到最后一行,再将所有满足条件的行做成记录集返回给客户端。

整个执行过程如下图(最后是存储引擎)

                                                  end