SQL执行顺序
连接
MySQL服务监听的端口默认是3306,客户端连接服务端的方式有很多种。可以是异步,同步,短连接,长连接,可以是TCP也可以是Unix Socket。
如何查看当前MySQL当前有多少个连接?
可以使用show global status ,模糊匹配Thread:
show global status like 'Thread%';
字段
含义
Threads_cached
缓存中的线程连接数
Threads_connected
当前打开的连接数
Threads_created
为处理连接创建的线程数
Threads_running
非睡眠状态的连接数,通常指并发连接数
为什么查看连接数是查看线程?客户端连接和服务端的线程是什么关系?
客户端每产生一个连接或者一个会话,在服务端就会创建一个线程来处理。想要杀死会话就要Kill一个线程。
mysql 有两个参数来管理不活动的连接。
show global variables like 'wait_timeout'; -- 非交互式超时时间,如JDBC
show global variables like 'interactive_timeout'; -- 交互式超时时间,如数据库工具
默认是28800秒,8个小时。
MySQL默认的连接数(并发数)是多少?
5.7版本中默认是151个,最大值可以设置为十万。
show variables like 'max_connections';
MySQL参数的作用域
有全局(Global)和会话(Session)基本,分别作用于全局和当前会话。并不是所有参数都拥有两种作用域。比如说,max_connections就只有全局级别。
当语句中没有Global时候,默认是Session级别。
比如下面这个只是临时修改,建议修改为session级别。如果需要在其他会话中生效,必须显式加上Global参数。
show variables like 'autocommit';
set autocommit = true;
建立完连接之后该怎么做呢?
查询缓存
mysql的默认缓存是关闭的。
show variables like 'query_cache%';
Variables
Value
query_cache_limit
1048576
query_cache_min_res_unit
4096
query_cache_size
1048576
query_cache_type
OFF
query_cache_wlock_invalidate
OFF
为什么默认关闭呢?
使用场景极其有限,SQL语句必须一模一样,中间不允许多一个空格,而且大小写敏感;表里有任何一条数据的变化产生的时候,这张表的缓存都会失效。对于有大量数据更新的应用,也不适合;
8.0版本中已经移除
语法解析和预处理(Parser & Preprocessor)
为什么一条SQL能被正确识别呢?
这是由Parser解析器和Preprocessor预处理来完成的。这一步主要就是对语句基于SQL语法进行词法和语法分析语义分析。
词法分析
把一个完整的SQL语句打散为一个个单词。
select name from `user` where id = 1;
这段SQL会被打散为8个符号,每个符号的类型,起始的位置。
语法分析
对SQL做一些语法检查,比如单引号是否闭合,再根据MySQ定义的语法规则,根据SQL语句生成一个数据结构。叫做解析树(select_lex)。
词法语法分析-解析树
词法语法分析,是一个非常基础的功能,Java的编译器、百度搜索引擎如果要识别语句,也必须要有词法语法分析的功能。
任何数据库的中间件,要解析SQL完成路由功能,也必须要有词法和语法分析的功能,比如MyCat,Sharding-JDBC(Druid Parser)。在市面上也有很多的开源词法解析工具(LEX,YACC)。
预处理器
问题:如果我写了一个条SQL,但是表名或者字段不存在,会在哪里报错?在数据库的执行层还是解析器?
select xxx from userxxxx;
其实还是在解析器这里报错,解析SQL的环节里面有一个预处理器。
预处理器会检查生成的解析树,解决解析器无法解析的语义。检查表和列名是否存在,检查名字和别名,保证没有歧义。
预处理之后,得到一个新的解析树。
查询优化器(Query Optimizer)与查询执行计划。
思考一下:得到解析树之后,是否就直接执行SQL语句了?一条SQL是否只有一种执行方法?数据库执行的SQL是否就是我们发送的SQL?
答案是否定的,一条SQL可以有很多种执行方式,最终返回相同的结果,他们是等价的。
多种的执行方式,如何得到,如何选择那种进行执行,根据什么标准判断?
这些都是MySQL的查询优化器模块Optimizer去完成的。
查询优化器根据解析树生成不同的执行计划(Execution Plan),然后选择一种最优的执行计划,MySQL里面使用的是基于开销(cost)的优化器,哪一种执