上节谈了关于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优化的更多相关文章

  1. MySql(八):MySQL性能调优——Query 的优化

    一.理解MySQL的Query Optimizer MySQL Optimizer是一个专门负责优化SELECT 语句的优化器模块,它主要的功能就是通过计算分析系统中收集的各种统计信息,为客户端请求的 ...

  2. mysql性能调优——锁优化

    影响mysql server性能的相关因素 需求和架构及业务实现优化:55% Query语句优化:30% 数据库自身优化:15% 很多时候大家看到数据库应用系统中性能瓶颈出现在数据库方面,就希望通过数 ...

  3. MySQL性能调优与架构设计——第8章 MySQL数据库Query的优化

    第8章 MySQL数据库Query的优化 前言: 在之前“影响 MySQL 应用系统性能的相关因素”一章中我们就已经分析过了Query语句对数据库性能的影响非常大,所以本章将专门针对 MySQL 的 ...

  4. MySQL性能优化总结___本文乃《MySQL性能调优与架构设计》读书笔记!

    一.MySQL的主要适用场景 1.Web网站系统 2.日志记录系统 3.数据仓库系统 4.嵌入式系统 二.MySQL架构图: 三.MySQL存储引擎概述 1)MyISAM存储引擎 MyISAM存储引擎 ...

  5. MySql(十一):MySQL性能调优——常用存储引擎优化

    一.前言 MySQL 提供的非常丰富的存储引擎种类供大家选择,有多种选择固然是好事,但是需要我们理解掌握的知识也会增加很多.本章将介绍最为常用的两种存储引擎进行针对性的优化建议. 二.MyISAM存储 ...

  6. MySQL性能调优与架构设计——第11章 常用存储引擎优化

    第11章 常用存储引擎优化 前言: MySQL 提供的非常丰富的存储引擎种类供大家选择,有多种选择固然是好事,但是需要我们理解掌握的知识也会增加很多.每一种存储引擎都有各自的特长,也都存在一定的短处. ...

  7. MySQL性能调优与架构设计——第10章 MySQL数据库Schema设计的性能优化

    第10章 MySQL Server性能优化 前言: 本章主要通过针对MySQL Server(mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化, ...

  8. MySQL性能调优与架构设计——第9章 MySQL数据库Schema设计的性能优化

    第9章 MySQL数据库Schema设计的性能优化 前言: 很多人都认为性能是在通过编写代码(程序代码或者是数据库代码)的过程中优化出来的,其实这是一个非常大的误区.真正影响性能最大的部分是在设计中就 ...

  9. MySQL性能调优——锁定机制与锁优化分析

    针对多线程的并发访问,任何一个数据库都有其锁定机制,它的优劣直接关系着数据的一致完整性与数据库系统的高并发处理性能.锁定机制也因此成了各种数据库的核心技术之一.不同数据库存储引擎的锁定机制是不同的,本 ...

随机推荐

  1. ES3之bind方法的实现模拟

    扩展Function原型方法,此处用myBind来模拟bind实现 Function.prototype.myBind = function(o /*,args*/){       //闭包无法获取t ...

  2. HttpWebRequest 以及WebRequest的使用

    1.WebRequest的发送数据以及接收数据 class Program { static void Main(string[] args) { //创建一个实例并发送请求 HttpWebReque ...

  3. Android学习笔记(九) SeekBar和RatingBar

    一.SeekBar的主要属性 -max -progress -secondaryProgress 二.onSeekBarChangeListener -onProgressChanged(SeekBa ...

  4. H.264学习笔记3——帧间预测

    帧间预测主要包括运动估计(运动搜索方法.运动估计准则.亚像素插值和运动矢量估计)和运动补偿. 对于H.264,是对16x16的亮度块和8x8的色度块进行帧间预测编码. A.树状结构分块 H.264的宏 ...

  5. 学习嵌入式开发板的Android平台体系结构和源码结构

    本文转自迅为论坛资料:http://www.topeetboard.com 推荐学习嵌入式开发板平台:iTOP-4412开发板 下面这张图出自Google官方,展示了Android系统的主要组成部分. ...

  6. swift 多态函数方式

    1.v-table:   class 2.WitnessTable protocol 3.消息派发. @objc dynamic

  7. 小b重排字符串

    2485 小b重排字符串 2 秒 262,144 KB 5 分 1 级题   小b有一个字符串S,现在她希望重排列S,使得S中相邻字符不同. 请你判断小b是否可能成功. 样例解释:将"aab ...

  8. Android中notifyDataSetInvalidated()和notifyDataSetChanged()有什么区别

     看下源码中对于这两个方法   public void notifyDataSetChanged () 该方法内部实现了在每个观察者上面调用onChanged事件.每当发现数据集有改变的情况,或者读取 ...

  9. 关键字搜索高亮jQuery插件

    // textSearch.js v1.0 文字,关键字的页面纯客户端搜索// 2010-06-23 修复多字母检索标签破碎的问题// 2010-06-29 修复页面注释显示的问题// 2013-05 ...

  10. [LUOGU] P1113 杂物

    题目描述 John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它.比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作.尽早将所有杂务完成是必要的,因为 ...