查询性能优化【《高性能mysql第三版》笔记】

前言

即使库表结构再合理、索引再合适,如果查询写得很糟糕,也无法实现高性能。
查询优化,索引优化,库表结构优化要齐头并进。

1. 为什么查询速度会慢

如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间。如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数,要么让子任务运行得更快。

通常来说, 查询的生命周期大致可以按照顺序来看:从客户端到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端。其中“执行”可以是整个生命周期中最重要的阶段,这其中包括了大量为了检索数据到存储引擎的调用以及调用后的数据处理,包括排序、分组等。

在完成这些任务的时候,查询需要在不同的地方花费时间,包括网络,CPU计算,生成统计信息和执行计划、锁等待(互斥等待)等操作,尤其是向底层存储引擎检索数据的调用操作,这些调用需要在内存操作、CPU操作和内存不足时导致的I/O操作上消耗时间。根据存储引擎不同,可能还会产生大量的上下文切换以及系统调用。

2. 慢查询基础:优化数据访问

查询性能低下最基本的原因是访问的数据太多,某些查询可能不可避免的需要筛选大量数据,但并不常见。大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化。对于低效的查询,我们发现通过下面两个步骤来分析总是很有效:

    1. 确认应用程序是否在检索大量超过了需要的数据,这通常意味着访问了太多的行或者列;
    1. 确认MySQL服务器层是否在分析大量超过需要的数据行。

3. 重构查询的方式

1. 一个复杂查询还是多个简单查询
2. 切分查询
image.png

image.png
3. 分解关联查询
image.png
4. 查询执行的基础
image.png

image.png
  • 4.1 MySQL客户端/服务器通信协议
    MySQL客户端和服务器之间的通信协议是“半双工”的,这意味着,在任何一个时刻,要么是由服务器向客户端发送数据,要么是有客户端向服务器发送数据,这两个动作不能同时发生。这种协议让MySQL通信简单快速,但是也从很多地方限制了MySQL。一个明显的限制是,这意味着没法进行流量控制,一旦一端开始发生消息,另一端要接收完整个消息才能响应它。


    image.png

    image.png
  • 4.2 查询缓存
    在解析一个查询语句之前,如果查询缓存是打开的,那么MySQL会优先检查这个查询是否命中查询缓存的数据,这个检查是通过一个对大小写敏感的哈希查找实现的。如果当前的查询恰好命中了缓存,那么在返回查询结果之前MySQL会检查一次用户权限。

  • 4.3 查询优化处理
    查询的生命周期的下一步是将一个sql转换成一个执行计划,MySQL再依照这个执行计划和存储引擎进行交互。这包括多个子阶段:解析sql、预处理、优化sql执行计划。这个过程中任何错误都可能终止查询。

MySQL使用基于成本的优化器,它将尝试预测一个查询使用某种执行计划时的成本,并选择其中成本最小的一个。MySQL的查询优化器是一个非常复杂的部件,优化策略简单地分为两种,一种是静态优化,一种是动态优化。静态优化可以直接对解析树进行分析,并完成优化。

静态优化可以通过简单的代数变换将where转换成另一种等价形式,它不依赖于特别的数值,第一次完成后就一直有效,即使使用不同的参数重复执行查询也不会发生变化。可以认为这是一种“编译时优化”。

动态优化则和查询的上下文有关,也可能和很多其它因素有关,例如where条件中的取值,索引中条目对应的数据行数等。这需要在每次查询的时候都重新评估,可以认为这是“运行时优化”。

  • 4.4 查询执行引擎
    在解析和优化阶段,MySQL将生成查询对应的执行计划,MySQL的查询执行引擎则根据这个执行计划来完成整个查询。执行只是简单地根据执行计划给出的指令逐步执行。
5 MySQL查询优化器的局限性
  • 1 关联子查询
    MySQL的子查询实现非常糟糕。最糟糕的一类查询是where条件中包含IN()的子查询语句。
    大部分情况下应该以连表代替子查询。

  • 2 UNION的限制


    image.png
  • 3 索引合并优化
    当where子句中包含多个复杂条件的时候,MySQL能否访问单个表的多个索引以合并和交叉过滤的方式来定位需要查找的行。

  • 4 等值传递

  • 5 并行执行
    不支持。

  • 6 哈希关联
    不支持。

  • 7 松散索引扫描
    不支持

  • 8 最大值和最小值优化
    MIN()和MAX()查询,MySQL的优化做得并不好。

  • 9 在同一个表上查询和更新
    不允许。

6 查询优化器的提示(略)
7 优化特定类型的查询
  • 1 优化COUNT()查询
    只适用MyISAM的:


    image.png
  • 2 优化关联查询
    -- 确保ON或者USING子句的列上有索引。在创建索引是时候要考虑到关联的顺序。当表A和B用c列关联的时候,如果优化器的关联顺序是B,A,那么就不需要在B表的对应列上建上索引。没有用到的索引只会带来额外的负担。一般来说,除非有其它理由,否则只需要在关联顺序中的第二个表的相应列上创建索引。

-- 确保任何的GROUP BY和ORDER BY中的表达式只涉及到一个表的列,这样MySQL才有可能使用索引来优化这个过程;

-- 当升级MySQL的时候注意:关联语法、运算符优先级等其它可能发生变化的地方。因为以前是普通关联的地方可能会变成笛卡儿积,不同类型的关联可能会生成不同的结果等。

  • 3 优化子查询
    尽量用关联查询替代。

  • 4 优化GROUP BY和DISTINCT
    在很多场景下,MySQL都使用同样的办法优化这两种查询。事实上,MySQL优化器会在内部处理的时候相互转化这两类查询。它们都可以使用索引来优化,这也是最有效的优化办法。

在MySQL中,当无法使用索引的时候,GROUP BY使用两种策略来完成:使用临时表或者文件排序来做分组。对于任何查询语句,这两种策略的性能都有可以提升的地方。可以通过使用提示SQL_BIG_RESULT和SQL_SMALL_RESULT来让优化器按照你希望的方式运行。


image.png

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容