13.mysql的查询过程(概括):

  • 客户端发送一条查询给服务器
  • 服务器先检查查询缓存,如果命中缓存立即返回缓存中的结果。
  • 服务器进行sql解析、预处理、优化器生成对应的执行计划
  • mysql根据优化器生成的执行计划,调用存储引擎的API来执行查询
  • 返回结果

14.mysql客户端和服务器通信协议是“半双工”的:任何一个时刻,不能同时发送数据。

15.客户端通过一个单独的数据包将查询传给服务器。一担客户端发送了请求,就只有等待结果了。

16.服务器给客户端的响应数据有很多,由多个数据包组成。当服务器开始响应客户端数据就必须接收完整的数据,所以最好响应的数据都是you有用的否则会花费时间接收无用的数据。(客户端没法让服务器停下来,因为是服务器推送数据,客户端被动接收)

17.mysql通常需要等所由的数据都发送给客户端才能释放这条查询所占用的资源。

18.在链接mysql的时候可以指定属性:让整个链接都使用不缓存的方式处理结果集。(mysql_use_result=1 使用)

查询状态

19.show full processlist 可以返回状态列表

  • sleep 等待客户端发送请求
  • query 正在执行查询或者正在将结果返回给客户端
  • locked 该线程正在等待表锁(innoDB的行锁不会体现出来)
  • analyzing and statistis 线程正在收集存储引擎的统计信息
  • copying to tmp table 线程正在执行查询,并且收集复制到一个临时表(一般是group by 或者是文件排序操作)[on disk] 表示mysql 将一个内存零时表放到磁盘上
  • Sorting result 线程正在对结果集进行排序
  • sending data 向客户端返回数据、正在生成结果集、在多个状态上

查询缓存

20.如果查询缓存打开,在查询到时候会首先查询缓存中的数据。检查是通过大小写敏感的哈希查找实现的。如果查询命中会在返回结果前判断用户权限。如果有权限就直接返回。

21.查询优化器会将解析器或者预处理生成的解析结果生成一个执行计划。mysql 会按照这个执行计划和存储引擎交互。

  • sql 没有缓存结果后的步骤:解析sql、预处理、优化sql执行计划。如果途中任何环节报错都可能终止查询。

语法解析器和预处理

22.mysql通过sql关键字将sql语句进行解析,并生成一个对应的解析树。解析器会使用mysql 的语法规则进行验证语法是否正确。(sql 的语法层面 ,字面层)

23.预处理器:检查一些简单的列名是否存在,是否有歧义,或者表是否存在。最后会验证是否有权限。(稍微和数据有些关系)至此语法树如果通过就说明是合法的。

查询优化器

24.将语法树转化为执行计划

25.优化器的作用就是找到最好的执行计划。

26.mysql 使用的是基于成本的优化器,可以通过 select sql_no_cache count(*) From table;show status like 'last_query_coust';优化器会不会考虑到缓存。

27.优化器可以简单的分为两种:

  • 静态优化:直接解析树,和参数无关,一次完成以后一直生效。
  • 动态优化:可以理解为运行时优化,在运行的时候根据上下文进行优化。(每次执行都会重新评估)

28.在mysql 中 in() 查询和 or 是不一样的。in的时间复杂度是O(log n) or 是O(n) 所以当in()列表中有大量的取值的时候mysql 的处理速度将会更快。