上节谈了关于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. H.264学习笔记5——熵编码之CAVLC

    H.264中,4x4的像素块经过变换和量化之后,低频信号集中在左上角,大量高频信号集中在右下角.左边的低频信号相对数值较大,而右下角的大量高频信号都被量化成0.1和-1:变换量化后的残差信息有一定的统 ...

  2. C#中的常量、类型推断和作用域

    一.常量 常量是其值在使用过程中不会发生变化的变量.在声明和初始化变量时,在变量前面家关键字const,就可以把该变量指定为一个常量: const int a=100;//a的值将不可以改变 常量的特 ...

  3. 最全的Java面试宝典

    一. 前言部分 从享受生活的角度上来说:“程序员并不是一种最好的职业,我认为两种人可以做程序员,第一,你不做程序员,你就没有什么工作可做,或者说是即使有可以做的工作但是你非常不愿意去做:第二,你非常痴 ...

  4. 6-Java-C(移动距离)

    题目描述: X星球居民小区的楼房全是一样的,并且按矩阵样式排列.其楼房的编号为1,2,3... 当排满一行时,从下一行相邻的楼往反方向排号. 比如:当小区排号宽度为6时,开始情形如下: 1  2  3 ...

  5. 不能局部安装webpack的解决方法

    npm ERR! code ENOSELFnpm ERR! Refusing to install package with name "webpack" under a pack ...

  6. cuda输出

    cuda的输出就是printf 可以在屏幕上显示出来,但你修改之后一定要make编译,不然只是修改了源代码,但生成的可执行文件还是之前编译的

  7. 使用soapUI5.3.0调试webservice接口(参数为XML格式)

    最近项目中经常要调试webservice接口,从朋友处了解到他们经常使用SoapUI,因此学习一下这个工具的使用,为避免遗忘,特地记录下来,分享分享... 下载 #####首先,下载SoapUI,我下 ...

  8. 2019年,Linux运维行业的趋势,跟不上学习就被淘汰

    运维行业经历了多年的发展,已经有了很大的变化,最开始的机房.网线.人肉,到现在一步步的自动化.智能化.容器化,运维人员的职业技能要求越来越高,稍不注意就可能被淘汰. 今天马小哥就来盘点一下2019年运 ...

  9. 第3节 hive高级用法:15、hive的数据存储格式介绍

    hive当中的数据存储格式: 行式存储:textFile sequenceFile 都是行式存储 列式存储:orc parquet 可以使我们的数据压缩的更小,压缩的更快 数据查询的时候尽量不要用se ...

  10. 第2节 mapreduce深入学习:12、reducetask运行机制(多看几遍)

    ReduceTask的运行的整个过程 背下来1.启动线程到mapTask那里去拷贝数据,拉取属于每一个reducetask自己内部的数据2.数据的合并,拉取过来的数据进行合并,合并的过程,有可能在内存 ...