mysql性能调优——Query优化
上节谈了关于mysql锁定机制的优化方案,下面来谈一下Query优化——Mysql Query Optimizer
当Mysql Query Optimizer接受到从Query Parser过来的Query时会根据相应语法进行分解分析,同时还会做很多其他的计算转化工作如常量转化,无效内容删除、常量计算等。所有这些工作都是为了Optimizer分析出最优的数据检索方式---执行计划。
Mysql Query Optimizer所有工作建立在Query Tree的基础上,QueryTree是通过优化实现DBXP的经典数据结构和Tree构造器而生成的,是指导一个完成一个Query语句的请求需要处理工作步骤,只是以Tree的数据结构存放而已。通过QueryTree可以很清楚的指导一个Query的完成需要经过哪些步骤,每一步的数据来源在哪里,处理方式是怎样的,在整个过程中,mysql使用了LEX和YACC这两个词法分析工具
Query语句优化基本思路:
1.优化更需要优化的query
2.定位优化对象的性能瓶颈
3.明确优化目标
4.从执行计划入手
5.多使用Profile
以上五点不是废话,只有清楚的知道了哪个地方是更需要优化的,性能瓶颈在什么地方,具体设计哪些对象,这样才能有效的优化,否则事倍功半。
Query优化原则:
1.永远使用小结果集驱动大结果集
2.尽可能在索引中完成排序
3.只取自己需要的列
4.仅仅使用最有效的过滤条件
5.尽可能避免复杂的join和子查询
解释一下以上五点。小结果集驱动,目的是减少循环,循环减少了,以为这被驱动表的IO减少了。索引中排序很好理解,所以是有顺序的,正是利用了这一点,不需要重新排序,否则性能会下降的很厉害。在一次查询中,很多人会取所有的列(select *),方便后续的扩展,并且他们认为多取得字段无非是占用网络的带宽造成延迟,可以忽略不计,其实最主要的影响是内存,mysql排序的算法是从原来的两次IO变成了一次,所有的排序等操作都是一次性取出来在排序区完成的,如果这时字段太多,内存势必会变大,当所占内存大到超过所设定的阈值,排序就会变成第一种算法,两次IO,性能会下降很多,所以尽量按需取值。where条件后并不是加的过滤条件越多越好,相反,如果索引太大会造成筛选的延迟,会造成性能的降低。mysql中所有的join都是嵌套查询,如果join复杂,会造成锁的对象多,高并发下延迟就大,造成性能的下跌,优化的方法是拆分查询,可以忽略多个查询的网络延迟和排队,牺牲一小部分性能让整理性能得以有较大幅度的提升。
索引
B+树:InnoDB存储引擎采用的是B+树存储数据,叶子节点存储数据或者数据地址,非叶子节点为索引值,叶子节点横向是一个链表,可以保证快速找到兄弟节点,快速遍历。
hash索引:基于哈希表实现,只有精确匹配到索引列的查询,才会起到效果。对于每一行数据,存储引擎都会对所有的索引列计算出一个哈希码(hash code),哈希码是一个较小的整数值,并且不同键值的行计算出来的哈希码也不一样。主要有Memory和NDB cluster存储引擎使用。实际上上通过一定的hash算法将需要索引的键值进行hash运算,然后将得到的hash值存入一个hash表,每次检索的时候使用相同的hash运算再和hash表中的hash值进行比较。在memory存储引擎中支持非唯一hash索引,相同的hash值将它们链接到同一个hash键值下,以一个链表的形式存在,检索的时候获取不同的键值过滤。由于键值的大小关系再经过hash运算后不能保证大小的顺序性,所以不能用于范围查询、排序操作,也不能利用组合索引中的部分索引功能。
Full-Text索引:仅MyISAM引擎支持。目前仅有CHAR、VARCHAR、TEXT支持Full-Text索引。主要用来替换效率低下的like。
索引优化:
1.较频繁的作为查询条件的字段应该创建索引
2.唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
3.更新非常频繁的字段不适合创建索引
4.不会出现在where子句中的字段不该创建索引
Join实现与优化
Join在Mysql中只有一种实现算法就是Nested Loop,通过驱动表的结果集作为循环基础数据,然后将该结果集中的数据作为过滤条件一条条的到下一个表中查询数据,最后合并结果,如果有第三张表,就用前两个表的结果作为查询条件,以此类推。
由此可以得出join优化思路:
1.尽可能减少Join语句中Nested loop的循环总次数
2.优先优化Nested loop的内层循环
3.保证join语句中被驱动表的join字段被索引
4.当无法join字段被索引,要设定较大的Join Buffer
Order by Group by Distinct优化
order by:有两种实现类型,第一种是通过索引直接取得有序的数据,直接返回客户端,运用了索引的有序性,另外一种是通过排序算法将存储引擎返回的数据排序后再返回。所以在优化的时候尽可能让索引覆盖排序字段,必要时可以添加索引字段。
第二种实现方式中mysql通过两种算法实现排序操作,第一种算法是取出过滤条件作为排序条件的字段,以及可以直接定位到行数据的行指针信息,在sort buffer中进行实际的排序操作,然后再利用排好序的数据根据行指针再去表中获取其他字段信息。
另外一种算法是一次性取出所有字段。将不需要排序的字段放在一块内存区域,然后再sort buffer中将排序字段和行指针信息进行排序,再和其他字段匹配得到结果。
优化:加大max_length_for_sort_data参数的设置、去掉不必要的返回字段、增大sort_buffer_size参数设置
group by:group by 实际上同样需要排序操作,而且与order by相比,groupby只不过是多了排序之后的分组,当然也可以在分组之后进行一些聚合函数计算,所以同样可以利用索引。
使用松散索引实现:这是最高效的方式,松散索引扫描读取的关键字数量与组数量一样多,可以比所有关键字数小得多。如果WHERE子句包含范围判断式, 松散索引扫描查找满足范围条件的每个组的第1个关键字,并且再次读取尽可能最少数量的关键字 。。有几个条件,group by字段必须处在同一个索引中的最前面的连续位置,只能使用max、min函数
使用紧凑索引实现:如果不满足松散索引扫描条件,GROUP BY查询仍然可以不用创建临时表。如果WHERE子句中有范围条件,该方法只读取满足这些条件的关键字。否则,进行索引扫描。该方法读取由WHERE子句定义的每个范围的所有关键字,或没有范围条件式扫描整个索引,我们将它定义为紧凑式索引扫描。
使用临时表实现:Group by如果想使用索引必须满足group by字段同时存放于同一个索引中,且是一个有序索引,还与是否使用聚合函数有关。无法使用索引时就不得不先读取所需数据,通过临时表来完成Group by操作
Distinct:和Group by非常类似,只是在group by分组之后每组只取出一条记录,没有聚合函数。
mysql性能调优——Query优化的更多相关文章
- MySql(八):MySQL性能调优——Query 的优化
一.理解MySQL的Query Optimizer MySQL Optimizer是一个专门负责优化SELECT 语句的优化器模块,它主要的功能就是通过计算分析系统中收集的各种统计信息,为客户端请求的 ...
- mysql性能调优——锁优化
影响mysql server性能的相关因素 需求和架构及业务实现优化:55% Query语句优化:30% 数据库自身优化:15% 很多时候大家看到数据库应用系统中性能瓶颈出现在数据库方面,就希望通过数 ...
- MySQL性能调优与架构设计——第8章 MySQL数据库Query的优化
第8章 MySQL数据库Query的优化 前言: 在之前“影响 MySQL 应用系统性能的相关因素”一章中我们就已经分析过了Query语句对数据库性能的影响非常大,所以本章将专门针对 MySQL 的 ...
- MySQL性能优化总结___本文乃《MySQL性能调优与架构设计》读书笔记!
一.MySQL的主要适用场景 1.Web网站系统 2.日志记录系统 3.数据仓库系统 4.嵌入式系统 二.MySQL架构图: 三.MySQL存储引擎概述 1)MyISAM存储引擎 MyISAM存储引擎 ...
- MySql(十一):MySQL性能调优——常用存储引擎优化
一.前言 MySQL 提供的非常丰富的存储引擎种类供大家选择,有多种选择固然是好事,但是需要我们理解掌握的知识也会增加很多.本章将介绍最为常用的两种存储引擎进行针对性的优化建议. 二.MyISAM存储 ...
- MySQL性能调优与架构设计——第11章 常用存储引擎优化
第11章 常用存储引擎优化 前言: MySQL 提供的非常丰富的存储引擎种类供大家选择,有多种选择固然是好事,但是需要我们理解掌握的知识也会增加很多.每一种存储引擎都有各自的特长,也都存在一定的短处. ...
- MySQL性能调优与架构设计——第10章 MySQL数据库Schema设计的性能优化
第10章 MySQL Server性能优化 前言: 本章主要通过针对MySQL Server(mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化, ...
- MySQL性能调优与架构设计——第9章 MySQL数据库Schema设计的性能优化
第9章 MySQL数据库Schema设计的性能优化 前言: 很多人都认为性能是在通过编写代码(程序代码或者是数据库代码)的过程中优化出来的,其实这是一个非常大的误区.真正影响性能最大的部分是在设计中就 ...
- MySQL性能调优——锁定机制与锁优化分析
针对多线程的并发访问,任何一个数据库都有其锁定机制,它的优劣直接关系着数据的一致完整性与数据库系统的高并发处理性能.锁定机制也因此成了各种数据库的核心技术之一.不同数据库存储引擎的锁定机制是不同的,本 ...
随机推荐
- CAD交互绘制虚线(com接口)
用户可以在控件视区任意位置绘制直线. 主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下: 参数 说明 DOUBLE dX1 直线的开始点x坐标 DOUBLE dY ...
- CAD参数绘制圆弧(com接口)
在CAD设计时,需要绘制圆弧,用户可以在图面点圆弧起点,圆弧上的一点和圆弧的终点,这样就绘制出圆弧. 主要用到函数说明: _DMxDrawX::DrawArc2 由圆弧上的三点绘制一个圆弧.详细说明如 ...
- freenas iscsi initiator 配置
1.加载Iscsi Initiator 模块 freebsd从7.0开始已经包含了Iscsi Initiator ,不需要安装后再使用,但在使用前,需要加载模块. # kldload -v iscsi ...
- clipboard 实现复制
html <textarea id="bar" cols="62" rows="5" autocomplete="off&q ...
- 【Hadoop】一、分布式数据库HBase简介
1.分布式数据库特点 说到数据库,我们最熟悉的是类似于mysql这样的关系型数据库,称为RDBMS.关系型数据库作为一种数据存储和数据检索的关键技术,它支持SQL语言的结构化查询,但是它天生不是为 ...
- hdfs深入:08、hdfs的JavaAPI以及如何解决winutils的问题
/** * 通过url注册的方式访问hdfs,了解,不会用到 * @throws Exception */ 以下为详细代码://1.注册hdfs的url,让java代码能识别hdfs的url形式URL ...
- source collection list
1.Anaconda:http://www.cnblogs.com/xiaoming123abc/p/6970890.html https://conda.io/docs/help-support.h ...
- BZOJ3545 Peaks 离线处理+线段树合并
题意: 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经 ...
- 零基础入门学习Python(30)--文件系统:介绍一个高大上的东西
知识点 os,os.path模块中关于文件.目录常用的函数使用方法 在使用os模块,需要先进行import操作: import os os模块中关于文件/目录常用的函数使用方法 函数名 函数作用 示例 ...
- flask 开发配置
flask 开发配置 一:在虚拟机里面安装ubuntu系统.略 二: apt install python3-pip #安装pip, pip3 install --upgrade pip 三: pip ...