高性能mysql 第六章查询性能优化 总结(上)查询的执行过程
6 查询性能优化
6.1为什么查询会变慢
这里说明了的查询执行周期,从客户端到服务器端,服务器端解析,优化器生成执行计划,执行(可以细分,大体过程可以通过show profile查看),从服务器端返回客户端结果。
而执行部分作为最重要的一环,需要做的事情比较多,而不合适的query往往让执行过程做了不必要的操作,或者不能使用更优秀的底层数据结构,从而用时更久。
6.2慢查询基础:优化数据访问
访问数据量多大,超过实际所需是慢查询的一个原因。导致这种情况的原因大致有两个
1.应用程序向mysql服务要求的了超过需要的,或重复的数据,比如select * 。
2.mysql服务器执行过程中访问了超过需要的数据。
我们先来看第一种原因
6.2.1向数据库请求了超过需要的数据
1.请求了超过需要的行,如没有使用limit,请求了100行数据,但是只使用了10行。
2.使用select * 返回了不需要的列数据,尤其是多表关联查询是情况更突出,应该做的是只返回我们需要的列。
3.客户端如果使用了缓存,并且该部分缓存被接下来的数据需求命中,那么就没有必要再向服务器发送数据请求。
6.2.2mysql扫描了额外的纪录
慢查询日志中的三个衡量查询开销的指标:1.响应时间,2。扫描行数,3.返回行数
1.响应时间
响应时间包括服务时间与排队时间。
响应时间在不同的服务器环境,应用环境下都会不同。文中提到使用‘快速上限法’(中文版译名):通过query的执行计划,计算需要的顺序io与随机io次数,再结合当前环境下一次io的时间。最后做一次加总可以获得一个‘参考值‘。(可以看出来,这样的一种方法实操性并不强,因为并不是每一个query我们都能相对准确的估算io次数,不同服务器环境下,甚至统一服务器的不同时间,io的效率也会不同。 不过这里我们可以看出来,io是执行过程中相对比较耗时的一步)
2.扫描行数与返回行数
扫描行数与返回行数单独都是不能体现出任何query的效率的,只有两者的比值才能说明该query筛选数据的能力。
3.扫描行数与访问类型
explain 中的type列列出了访问类型:全表扫;索引扫描;范围扫描;单值查询
6.3重构查询的方式
6.3.1一个复杂的查询还是多个简单的查询
由于mysql的网络协议是‘半双工’的,连接断开的花费并不大,所以很多时候分解查询是优化的sql的一个有效方式。
6.3.2切分查询
切分查询是指对大的查询采取分而治之的策略,分时段分但服务器端的压力。但次执行分段的sql都是一样的,只是通过do_query()返回的数据与limit实现对数据条目的分批处理。
6.3.3分解关联查询
将关联查询分解成多个sql步骤。
这样做是减小事务的粒度,能够缓解锁的争用,也能让缓存的数据更加模块化,易于使用缓存。
6.4查询的执行步骤
客户端请求数据-->服务器端查询缓存,命中返回,未命中-->mysql解析sql,预编译,生成执行计划-->调用数据库引擎api执行sql-->返回结果到客户端
6.4.1mysql通信协议
‘半双工’。即同一时间,只有一方在发送数据,只有在接受完对方发送的数据,才可以向对方发出响应。
这里提到了客户端获取数据的两种方式,在c#一种是dateset,即一次性返回数据,在客户端保存数据快照(缓存),一种dateread是保持客户端与服务器端的连接,客户端随时查询数据。--不同的语言提供了不同的调用方式。
查询状态
指的是查询的进程的执行状态:需要注意的是sort result对结果集排序;sanding date表示自生成结果集或者在向客户端返回数据。
6.4.2查询缓存
就是查询步骤中的第二步查询的结构。第七章中有介绍。
6.4.3查询优化
即是查询步骤中的第三步
1.语言解析器与预处理器
解析器对语法进行检查,预处理器检查语义并检查用户是否有权限。
2.查询优化器
优化器对预处理器生成的预处理树进行执行计划的测算,计算各种执行计划的花费(有前面的知识我们知道,这里的花费往往指的是查询需要访问的数据页的多少)
可以明白:优化器对成本的测算并不是啊完全准确的,但是对于大多数sql,io都是它的执行瓶颈所在。
注意优化器并不会考虑缓存(有缓存的话不应该第二步就命中,返回给客户端了吗。
优化有静态优化与动态优化的区分,考虑到第七章查询缓存部分与存储过程的描述,我在考虑mysql是否保存执行计划呢?如何保存sql的执行计划的呢?静态动态优化时二选一还是并存呢?
书中列出了10多中优化器能够优化的查询,我不在一一列举。
- 数据索引的统计信息
Myisam引擎保存了count,而innodb只能提供估算值(innodb的数据与索引是纠缠的,插入删除修改还可能导致页分裂,页合并等问题,所以保存一个count之类的统计值维护不易)
4.关联查询的执行
Mysql的关联查询可以看做一个双循环或者多循环,只有两个表的关联查询,外侧循环的表叫外表,内侧循环的表叫内表。可以知道内侧循环的查询次数是远多于外侧的,所以内表非常需要一个合适的索引。
5.关联查询优化器
但是内外表常常不是我们可以决定的,mysql优化器会在其中起作用,优化器会建立一颗深度优先树,通过不同的组合得出花费最少的执行计划。不过在关联的表n过多时执行计划树的颗数会指数上升,n超过optimizer_search_depth就不再使用穷举的方式了,而是使用别的搜索方式获取最优执行计划。
上一段中mysql对关联查询的执行方式是嵌套循环,执行计划表现为一颗深度优先树。
- 排序优化
第三章中介绍了索引排序,这里介绍filesort。
Filesort文件排序,filesort并不总是要用到磁盘,当数据量较小时可以再内存中进行。
数据量是否大于文件缓冲区是两者的分水岭。当使用磁盘排序是相当于外排序。
Mysql filesort排序策略
两次读取数据(旧版):只使用行指针与排序字段做排序,这样排序结果需要通过行指针才能读取到全部数据,由于是随机io,io效率低。
单次读取数据(新版):先读取所需要的列,然后在根据给定列进行排序。
两个各有优劣,这个讨论我们放在第8章中
5.6版本在这里做出了改进,当使用limit时,mysql不再对所有结果排序,而是仅对需要的数据排序。
6.4.4查询执行引擎
Mysql的执行计划是一个数据结构,执行该执行计划时,需要调用存储引擎是响应的‘handler api’实现。如果是所有存储过程共有的特性,一般是服务器层实现的,如日期函数,视图,触发器。
6.4.5返回数据
Mysql执行sql过程中,开始生成第一条结果时就开始返回数据,这样是的服务器不需要保存大量的结果。(往后看可以发现union会到这个需要新建一个临时表来保存数据,前部union段执行完成才能返回数据)
高性能mysql 第六章查询性能优化 总结(上)查询的执行过程的更多相关文章
- mysql笔记03 查询性能优化
查询性能优化 1. 为什么查询速度会慢? 1). 如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减 ...
- Sql Server查询性能优化之走出索引的误区
据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是, ...
- MySQL性能调优与架构设计——第9章 MySQL数据库Schema设计的性能优化
第9章 MySQL数据库Schema设计的性能优化 前言: 很多人都认为性能是在通过编写代码(程序代码或者是数据库代码)的过程中优化出来的,其实这是一个非常大的误区.真正影响性能最大的部分是在设计中就 ...
- MySQL查询性能优化(精)
MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...
- 170727、MySQL查询性能优化
MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...
- 到底该不该使用存储过程 MySQL查询性能优化一则
到底该不该使用存储过程 看到<阿里巴巴java编码规范>有这样一条 关于这条规范,我说说我个人的看法 用不用存储过程要视所使用的数据库和业务场景而定的,不能因为阿里巴巴的技术牛逼,就视 ...
- MySQL查询性能优化七种武器之索引下推
前面已经讲了MySQL的其他查询性能优化方式,没看过可以去了解一下: MySQL查询性能优化七种武器之索引潜水 MySQL查询性能优化七种武器之链路追踪 今天要讲的是MySQL的另一种查询性能优化方式 ...
- Mysql优化系列之查询性能优化前篇1
前言 这是优化系列的最后一篇的第1小篇,我们其实可以直接从sql怎么写讲起,why not?但是我还是决定花2个篇幅 问一些问题,带着几个问题循序渐进的往下走. 一个sql语句是怎么被执行的? sql ...
- Mysql数据库调优和性能优化
1. 简介 在Web应用程序体系架构中,数据持久层(通常是一个关系数据库)是关键的核心部分,它对系统的性能有非常重要的影响.MySQL是目前使用最多的开源数据库,但是mysql数据库的默认设置性能非常 ...
随机推荐
- vue和react全面对比(详解)
vue和react对比(详解) 放两张图镇压小妖怪 本文先讲共同之处, 再分析区别 大纲在此: 共同点: a.都使用虚拟dom b.提供了响应式和组件化的视图组件 c.注意力集中保持在核心库,而将其他 ...
- day12_python_1124
00 如何学习python 如何学好英语? 母系英语. 听 说 读 写 练 input output 听 说 读 写(练) 听,读 说 纠正 01 昨日内容回顾 生成器:本质就是迭代器,自己用pyth ...
- .net Monitor产生SynchronizationLockException异常的原因
有时在使用Monitor进行并发同步编程时,会产生SynchronizationLockException异常,抛出的异常内容是"Object synchronization method ...
- JDBC遇到向ORACLE数据库表执行插入操作时,报错“列在此处不允许”
此异常的原因在于,编写的SQL语句,其中的变量已经成了字符串,这种情况对数值类数据没有影响,但是对字符串类数据有影响,应该在SQL语句中的字符串类变量左右两边加上单引号.如下:
- 马凯军201771010116《面向对象程序设计(java)》第一周学习总结
马凯军201771010116<面向对象程序设计(java)>第一周学习总结 第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.co ...
- java学习笔记39(sql事物)
在之前的学习中,我们学习了使用PreparedStatement类,使用这个类消除了sql注入的隐患,可是,还有些一些其他的隐患,这里以银行转账业务为例, 假设 一个银行,张三在里面存了1000元, ...
- windows环境安装MySQL
转:https://www.cnblogs.com/ayyl/p/5978418.html windows环境安装MySQL mySQL下载链接:MySQL Installer 5.7 :http:/ ...
- 安装pitchpork 及 pacbioscience 的问题及解决
1. error while loading shared libraries: libpbbam.so: cannot open shared 解决: find -name libpbbam.so ...
- Linux学习man page
1.3.8需要记住,分别代表用户操作.函数库和管理指令. ##man -f command 显示出命令的所有说明文档.等同于 whatis ##man -k key 显示出带key的所有说明文档.等同 ...
- Gym - 101490F:Endless Turning (半平面交)
pro:给定R条街道,现在小孩在某条街上骑车车,最开始他沿着所在街道向东(1,4象限的方向)驶去,如果他遇到街道的交叉口,他会右转.问他转N次后在哪个街道.有特殊情况是他一只遇不到交叉口,会沿着街道一 ...