高性能MYSQL(四)

可以通过explain 语句来对查询进行查看.对可优化的地方做出改进

前言

优化的主要组成部分:

  • 查询语句的优化
  • 索引设计的优化
  • 库表设计的优化

一个查询操作实际上是多个子任务组成,优化查询实际上是优化子任务的执行

  • 一个查询的子任务清单:

    • 网络IO
    • 磁盘IO
    • CPU计算
    • 互斥锁等待

优化数据访问

避免存储多余数据

  • 避免大量无用数据存在于数据表中,加大查询语句的执行复杂度
  • 避免大量无用的行

避免无用的查询

  • 例如在分页查询时,添加合适的LIMIT
  • 联查时只取出有用的数据,避免下面的“一把抓“式的请求
SELECT * FROM A INNER JOIN B WHRER A.ID = B.A_ID
  • 按需取出响应的列
  • 添加缓存
  • 在慢查询日志中,分析一个查询的查询时间是否合理可以利用快速上限法进行估量: 估算这个查询大约会经过的随机IO数 * 具体硬件下一次IO的时间,对查询进行估计
  • 优化联查!优化联查!联查时扫描的行是 矩阵式的 M * N ,很恐怖,所以找到好的对饮关系是优化联查的

重构查询时的方式

一个复杂的查询还是多个简单的查询

对于mysql 来说,MYSQL从设计上让连接和断开链接都很轻量级,在返回一个小的查询结果方面很高效。对于网络链接来说现代网络链接的效率相对与磁盘IO的效率来说已经不是问题。通常来将,两者的区别不仅仅在于传输速度,磁盘IO在查询时还有Lookup的过程。

对于复杂的查询来说,将其分解成多个简单的查询。或许效率更快些。但是同样的,具场景具体分析

将复杂的操作切分带来的另一个好处是可以分解复杂操作长时间对于读/写锁长时间占有,从而避免影响其他业务操作的执行

image.png
  1. 客户端发送一条查询给服务器
  2. 服务器首先查询缓存。如果命中,则立即返回存储在存储在缓存中的结果。否则进入下一阶段
  3. 服务器端进行SQL解析,预处理,再由优化器生成对应的执行计划
  4. MYSQL根据优化器生成的执行计划,调用存储引擎的API来执行查询
  5. 将结果集返回给客户端

MYSQL 客户端和服务器端通信

总的来说,MYSQL客户端和服务器端是一个半双工的通信状态,也就是说,在同一个时间,只能有一端像另一端发送数据(不要被JDBC的线程池的概念混淆)

SHOW ALL PROCESSLIST

各个MYSQL链接对应的状态 :

  • SLEEP : 线程正在等待客户端发送新的请求
  • QUERY : 线程正在执行查询或者正在将结果发送给客户端
  • LOCKED : 线程正在等待表锁
  • Sending Data : 这表示多种情况: 线程可能在多个状态之间传送数据,或者在 生成结果集,或者在客户端返回数据

查询缓存

查询缓存是通过一个对 大小写敏感的哈希查找实现的。如果缓存中缓存有对应数据。数据会直接返回给客户端。

  • 上面的这个大小写敏感,不代表SQL语法关键字敏感。
  • 虽然语法检查在查询缓存之后,但是你可以考虑到这一点。语法错误的查询在第一次执行的就没成功,就不会有缓存!

查询处理优化

查询的下一周期是将一个SQL 转换为一个执行计划,MYSQL再依照这个计划和存储引擎进行交互。这包括多个子阶段:解析SQL,预处理,优化SQL执行计划。

语法解析器和预处理

阶段所做工作

  • 语法解析器负责语法检查
  • 预处理器根据MYSQL规则 进一步检查 解析树是否合法,例如检查数据表和数据列是否存在,还会解析名字和别名,看他们是否有歧义

查询优化器

  • 可以通过 show status like 'Last_query_cost'的值来得知MYSQL计算的当前查询的成本
explain SELECT * FROM commonservice.regions where amapid is not  null;

show  status like 'Last_query_ cost'
Variable_name Value
'Last_query_cost' '142998.599000'

上面的查询结果上面的查询需要 142998个数据页的随机查找才能完成这个查询。当然这只是查询优化器的评估结果,且优化器在评估时不会考拉

  • 影响MYSQL 错误选择执行计划的因素

    • 统计信息不准确,例如:InnoDB因为其MVCC的架构,并不能维护一个数据表的行数的精确统计信息
    • 执行计划中的成本估算不等于实际执行计划,也就是说优化器给出的执行计划也可能不是最优的,比如说,有些页面读取虽多,但是其页面大部分都是顺序读写。
    • MYSQL 从不考虑其他并发执行的查询,这可能会影响当前查询速度
      MYSQL 的查询优化的优化策略分为两种
  • 静态优化 : 静态优化不依赖于特别的数值,如WHERE 条件中带入的一些常数等,静态优化在第一次完成后就一直有效,即使使用不同的参数重复查询也不会发生变化,可以将静态优化认为是一种 “编译时优化”

  • 动态优化 : 动态优化则和查询的上下文有关,例如WHERE 条件中的取值,索引中条目对应的数据行数等,这需要在每次查询的时候重新评估 可以将动态优化认为是一种”运行时优化“

MYSQL能够优化的的类型

重新定义关联表的顺序 : 数据表的关联并不是按照在查询中指定的顺序执行
将外链接转换为内链接 : 并不是所有的OUTER JOIN 语句都必须以外链接的方式执行。例如,WHERE条件,库表结构都可能会让外链接等价于一个内连接

  • 使用等价变换规则 利用等价变换来简化病规范表达式
  • 优化COUNT() ,MIN() ,MAX() : 通过B-Tree索引 直接查找其中的一个方向
  • **预估并转化为常数表达式 : **
  • 覆盖索引扫描 : 当索引中的列包含查询中需要的列,MYSQL会直接返回索引对应的列,不再去查表
  • **子查询优化 : ** Mysql 在某些情况下可以将子查询转换为一种效率更高的形式,从而减少多个查询对数据进行访问
  • 提前终止查询: 当发现已经满足查询需求的时候,MYSQL 总是能够立刻终止查询。比如使用LIMIT语句或者发现了一个不成立的条件,这时候MYSQL会立即返回一个空结果
  • 列表IN ()的优化 : ** 在MYSQL 中,MYSQL首选将IN()列表中的数据先进行排序,然后通过二分查找的方式来确定列表中的值是否满足条件(时间复杂度 : O(lgN) ),如果等价的转换为OR操作的话,时间复杂度为 O(n) :所以说 单列 多值匹配时,利用IN () 效率会更高**

Mysql 如果执行关联查询

  • 对于UNION查询,MYSQL先将一系列的单个查询结果放到一个临时表中,然后再读出临时表中数据完成UNION查询

执行计划 : MYSQL 并不会生成查询字节码来执行查询。MYSQL生成查询的一颗指令树,然后通过存储引擎执行完成这可指令树并返回结果。最终执行计划包含了重构查询的全部信息

优化特定类型的查询

优化COUNT()查询
  1. 如果想要查询行数,使用count() 进行查询,如果在count()函数中指定了某列,查询的是这个列有值(非 NULL)的值的个数!
优化关联查询
  1. 确保ON或者USING 子句的列上有索引,一般来说,除非有其他理由,否则只需要在关联顺序中的第二个表上建立索引
  2. 确保仁和Group by 或者Order by中的表达式只涉及到一个表中的列
GROUP By 和 DISTINCT
  1. 在无法使用索引的时候,GROUP BY使用临时表或者文件排序来分组
  2. 如果需要对 关联查询做分组,并且是按照查找表中的某个列进行分组,那么通常采用查找表的标识列分组的效率比其他列更高
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • 国庆第二天,今天嗨翻模式的开启就等室友的同学来了再说吧,在这之前,先来一波笔记 查询真正重要的是响应时间,查询包含...
    小炼君阅读 1,671评论 0 50
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 《高性能MySQL》&《MySQL技术内幕 InnoDB存储引擎》笔记 第一章 MySQL架构与历史 MySQL的...
    xiaogmail阅读 12,714评论 0 39
  • 2017年元旦前后在虹桥机场书店里买了三本杂志:商业周刊中文版总371期,第一财经周刊总435期,凤凰周刊总601...
    天光阅读 275评论 0 1
  • 看了些别人随便写写的想法和感受,我发现,应该是都有各自的特色吧。但,我好像是不太会吧?不太会把自己的想法或感受用文...
    一半天空_fly阅读 261评论 -1 1