本文已参与[新人创作礼]活动,一起开启掘金创作之路。
在java后端的工作学习中,执行sql语句一个普通的不能再普通的步骤了。但是一条sql语句到底是怎么执行的呢?数据库引擎对sql语句的执行顺序又是怎么样的呢?我们设置的索引又是怎么在sql语句执行时启到作用的呢?
抱着这些问题,我们一起来学习学习一条sql的执行之路到底是怎样的。 **
one
在明白sql的执行之前,我们得先明白我们的项目是怎么和数据库产生链接的。这就是 MySQL 驱动的工作原理了,在搭建一个项目的时候我们都会增加一个数据库的驱动依赖,就是为了给项目增加上数据库的链接能力。总结来说MySQL驱动就是帮我们链接上数据库,然后把我们的sql语句传输至数据库中。
two
项目拥有了MySQL 驱动后,我们每次执行一次sql语句都会先创建再销毁一次数据库链接,这样明显是不合理的,会极大的影响性能。所以数据库连接池技术变得不可或缺了,常见的数据库链接池有Druid、C3P0、DBCP。总结一下,数据库连接池帮助我们创建,调用,销毁数据库链接,避免了每次执行sql语句对数据库资源的浪费。
three
现在我们的sql语句终于来到了 mysql里面,接下来sql语句会 数据库连接器的身份验证和权限相关的检查。然后对语句进行查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用),没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确(一般语句写的不对,这里就会抛出错误)。最后- 优化器: 按照 MySQL 认为最优的方案去执行。
four
最后我们学习下一个查询语句是怎么在优化器里面被执行的。
- FORM: 对FROM的左边的表和右边的表计算笛卡尔积。产生虚表VT1
- ON: 对虚表VT1进行ON筛选,只有那些符合 的行才会被记录在虚表VT2中。 (即内连接查询,完全匹配)
- JOIN: 如果指定了OUTER JOIN(比如left join、 right join),那么保留表中未匹配的行就会作为外部行添加到虚拟表VT2中,产生虚拟表VT3, 如果from子句中包含两个以上的表的话,那么就会对上一个join连接产生的结果VT3和下一个表重复执行步骤1~3这三个步骤,一直到处理完所有的表为止。
- WHERE: 对虚拟表VT3进行WHERE条件过滤。只有符合 的记录才会被插入到虚拟表VT4中。
- GROUP BY: 根据group by子句中的列,对VT4中的记录进行分组操作,产生VT5.
- CUBE | ROLLUP: 对表VT5进行cube或者rollup操作,产生表VT6.
- HAVING: 对虚拟表VT6应用having过滤,只有符合 的记录才会被 插入到虚拟表VT7中。
- SELECT: 执行select操作,选择指定的列,插入到虚拟表VT8中。
- DISTINCT: 对VT8中的记录进行去重。产生虚拟表VT9.
- ORDER BY: 将虚拟表VT9中的记录按照 <order_by_list> 进行排序操作,产生虚拟表VT10.
- LIMIT:取出指定行的记录,产生虚拟表VT11, 并将结果返回。
sql执行完成后,把结果返回给我们的服务器,一条sql的使命也完成了。