MySql查询过程 几点记要

来源:互联网 发布:淘宝大件物流怎么设置 编辑:程序博客网 时间:2024/06/07 02:23

客户端和服务器的通信:

是半双工的,同一时刻,只有一端能向另一端发送数据,而且这时一端没办法通知另一端关闭连接,停止发送。MySql的客户端会缓存服务器传来的数据,但有时,因为传输的数据过大,为了不让缓存占据内存,我们可以设置不使用缓存

查询缓存:

只有当查询的语句完全一致(通过哈希查询实现,大小区分)才会命中,命中后直接检查用户权限,之后直接返回数据给客户端

查询优化处理:

  • 语法解析和预处理:根据SQL生成语法解析树,并解析语法错误,预处理器检查解析树是否存在数据上的错误
  • 查询优化器:选择最好的执行计划,包括对语句的优化,对关联顺序的优化,使用索引等

查询执行引擎:

相较查询处理优化阶段,执行引擎阶段仅是将执行计划利用存储引擎提供的接口执行,并不复杂

返回结果给客户端

在服务器从存储引擎得到查询结果,处理外关联表,生成第一条数据的时候,就可以将结果封装成数据包,在tcp上返回给客户端,由前面提到的,连接是半双工的,客户端不能在这时主动断开连接

查询优化处理的限制

基于查询成本的预测,选择成本最小的查询方式,但是预测可能出错,出错可能来源于:
* 统计信息不准确:比如因为MVCC对一条记录可能存在多份,所以InnoDB统计受影响行数并不准确
* 预估不准确:MySql的查询优化只是预测,所以对于IO操作,可能执行的时候存在读缓存、内存,顺序读,但MySql在预测的时候并不知道
* 基于规则的优化局限:某些情况下,MySql不会基于成本优化,而是基于规则,比如存在全文搜索Match()子句的时候,则在存在全文索引时一定是用全文索引,即便其他索引和where条件可能更快
* 对未知成本不考虑:如储存过程和用户自定义函数
* 不考虑其他并发执行的查询

查询优化器的限制

  • 关联子查询:对于关联子查询,使用in,exists的时候,性能可能很糟糕,但是仅仅是可能,还需要测试验增,修改方式是修改为join或者在使用in的时候使用GROUP_CONCAT构造一个用逗号分隔的列表
  • UNION的限制:对于使用limit等限制返回结果的关键字,MySql可能无法把这些限制下放到子查询的表中,所以可能出现读取关联表的全部记录后,union出仅几条记录返回的情况,修改方式是手动在子查询中限制
  • 松散索引扫描:MySql并不支持松散索引,这导致对于多列索引,无法跳过第一列索引而是用第二列索引,在5.0版本之后的某些情况下,可以使用松散索引
  • 最大值最小值
  • 不能对同一张表同时进行查询和更新:由于MySql写时加锁不能再读,所以不行,解决方法是再套一层select,将查询结果变成一个临时表,对临时表的读,写目标表