Mysql优化手册

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Mysql优化

前言

SQL优化中就三点:

    • 最大化利用索引
    • 尽可能避免全表扫描
    • 减少无效数据的查询

    一、解各种SQL 的执行频率

    1.1 SHOW STATUS

    show[session|global] status 可以根据需要加上参数“session”或者“global”来显示session 级(当前连接)的统计结果和global 级(自数据库上次启动至今)的统计结果。如果不写,默认使用参数是“session”。

    image.gifimage.gifa1.png

    Com_xxx 表示每个xxx 语句执行的次数,我们通常比较关心的是以下几个统计参数。

      • Com_select:执行select 操作的次数,一次查询只累加1。
      • Com_insert:执行INSERT 操作的次数,对于批量插入的INSERT 操作,只累加一次。
      • Com_update:执行UPDATE 操作的次数。
      • Com_delete:执行DELETE 操作的次数。

      1.2 SHOW PROCESSLIST

      通过该命令来查看当前mysql在进行的线程,

      image.gifa2.png

      1.3 EXPLAIN

      我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描,这都可以通过explain命令来查看。

      image.gifa3.png

      如果id一样,则表示从上而下加载,如果id值不同,则越大表示优先级越高。

      image.gifa4.png

      mysql查看性能工具explain中type有很多种,主要的有:     type的值对优化很重要

      链接类型 说明
      system 表只有一行MyISAM引擎。这是const类型的特例
      const 常量连接,表最多只有一行匹配,通用用于主键或者唯一索引比较时
      eq_ref 每次与之前的表合并行都只在该表读取一行,这是除了system,const之外最好的一种,特点是使用=,而且索引的所有部分都参与join且索引是主键非空唯一键的索引
      ref 如果每次只匹配少数行,那就是比较好的一种,使用=或<=>,可以是左覆盖索引或非主键非唯一
      fulltext 全文搜索
      ref_or_null ref类似,但包括NULL
      index_merge 表示出现了索引合并优化(包括交集,并集以及交集之间的并集),但不包括跨表和全文索引。这个比较复杂,目前的理解是合并单表的范围索引扫描(如果成本估算比普通的range要更优的话)
      unique_subquery 在in子查询中,就是value in (select…)把形如select unique_key_column的子查询替换。PS:所以不一定in子句中使用子查询就是低效的!
      index_subquery 同上,但把形如”select non_unique_key_column“的子查询替换
      range 常数值的范围
      index 索引树扫描。a.当查询是索引覆盖的,即所有数据均可从索引树获取的时候(Extra中有Using Index);b.以索引顺序从索引中查找数据行的全表扫描(无 Using Index);c.如果Extra中Using Index与Using Where同时出现的话,则是利用索引查找键值的意思;d.如单独出现,则是用读索引来代替读行,但不用于查找
      all 全表扫描(full table scan)

      从下到上,越来越好

      二、优化order by 语句

      2.1 mysql中的两种排序方式

        • 通过有序索引顺序扫描直接返回有序数据,不需要额外的排序,操作效率较高。因为索引的结构是B+树,索引中的数据是按照一定顺序进行排列的,所以在排序查询中如果能利用索引,就能避免额外的排序操作。EXPLAIN分析查询时,Extra显示为Using index。
        • Filesort排序,对返回的数据进行排序:所有不是通过索引直接返回排序结果的操作都是Filesort排序,也就是说进行了额外的排序操作。EXPLAIN分析查询时,Extra显示为Using filesort。

        ORDER BY优化的核心原则:尽量减少额外的排序,通过索引直接返回有序数据。

        示例:先查看userinfo表中索引情况

        image.gifa5.png

        order by 优化

        2.2 查询的字段,应该尽可能只包含此次查询使用的索引字段和主键,其余的非索引字段和索引字段作为查询字段则不会使用索引。

        image.gifa6.png

        2.3 排序字段在多个索引中,无法使用索引排序,查询一次只能使用一个索引:

        image.gifa7.png

        所以,只查询索引字段和主键时,可以利用索引来排序。

        MySQL默认的InnoDB引擎在物理上采用聚集索引这种方式,按主键进行搜索,所以InnoDB引擎要求表必须有主键,即使没有显式指定主键,InnoDB引擎也会生成唯一的隐式主键,也就是说索引中必定有主键。

        2.4 排序字段顺序与索引列顺序不一致,无法利用索引排序

        image.gifa8.png

        2.5 ORDER BY排序字段要么全部正序排序,要么全部倒序排序,否则无法利用索引排序。

        image.gifa9.png

        三、优化GROUP BY语句

        3.1 首先看是否有临时表的创建,临时表会使索引失效

          • 如果GROUP BY 的列没有索引,产生临时表
          • 如果GROUP BY时,SELECT的列不止GROUP BY列一个,并且GROUP BY的列不是主键 ,产生临时表
          • 如果GROUP BY的列有索引,ORDER BY的列没索引.产生临时表
          • 如果GROUP BY的列和ORDER BY的列不一样,即使都有索引也会产生临时表
          • 如果GROUP BY或ORDER BY的列不是来自JOIN语句第一个表.会产生临时表
          • 如果DISTINCT 和 ORDER BY的列没有索引,产生临时表

          可以看到这里不仅创建了临时表,还进行了文件排序

          image.gifa10.png

          学习了ORDER BY优化,就知道文件排序效率低,那么可以在这里使用ORDER BY NULL来禁止排序

          image.gifa11.png

          对于不创建临时表的优化可以针对上文例举会产生临时表的情况进行优化。

          四、优化嵌套查询

          子查询有些情况下可以被更有效的连接(JOIN)替代。因为连接(JOIN)不需要再内存中创建临时表来完成

          示例:

          image.gifa12.png

          通过以下sql来查询有角色的用户信息,此时就是通过子查询来完成的

          image.gifa13.png

          看一下执行情况

          image.gifa13.png

          当使用连接来完成上述查询时

          image.gifa14.png

          五、优化OR语句

          对于or语句,如果要利用索引,则or之间的每个条件都必须有索引。并且不走复合索引,必须是单列索引

          首先来看一下userinfo表中的索引情况

          image.gifa15.png

          示例:  此时发现是全表扫描

          image.gifa16.png

          当or的条件是索引时,range指的是有范围的索引扫描,相对于index的全索引扫描

          image.gifa17.png

          优化:使用UNION 来替换OR     type变成了const,而const的效率是远高于range的

          image.gifa18.png

          六、索引提示

          6.1 USE INDEX()

          在你查询语句中表名的后面,添加 USE INDEX 来提供你希望 MySQ 去参考的索引列表,就可以让 MySQL 不再考虑其他可用的索引。

          还是先看一下表中索引情况:一个包括name的复合索引,一个name的单例索引

          image.gifa19.png

          此时查询mysql要判断使用哪个索引

          image.gifa20.png

          当我们在sql中添加use index(), 去给mysql提供参考,注意仅仅是提供参考

          image.gifa21.png

          6.2 IGNORE INDEX()

          和USE INDEX()正好相反,这个是不想用哪个索引,用法是一样的。

          image.gifa22.png

          6.3 FORCE INDEX()

          在查询的时候,数据库系统会自动分析查询语句,并选择一个最合适的索引。但是很多时候,数据库系统的查询优化器并不一定总是能使用最优索引。如果我们知道如何选择索引,可以使用FORCE INDEX强制查询使用指定的索引。

          SELECT * FROM students FORCE INDEX (idx_class_id) WHERE class_id = 1 ORDER BY id DESC;

          image.gif

          七、模糊查询

          查看表中索引情况,在REALNAME字段上已经创建索引。

          image.gifa24.png

          7.1 尽量避免在字段开头模糊查询,会导致数据库引擎放弃索引进行全表扫描。

          image.gifa25.png

          image.gifa26.png

          八、尽量不要使用!= 和 <>

          如确实业务需要,使用到不等于符号,需要在重新评估索引建立,避免在此字段上建立索引,改由查询条件中其他索引字段代替。

          image.gifa27.png

          九、隐式类型转换造成不使用索引

          如下SQL语句由于索引对列类型为varchar,但给定的值为数值,涉及隐式类型转换,造成不能正确走索引。

          此时应该加上双引号

          select col1 from table where col_varchar=123;

          image.gif

          十、调整Where字句中的连接顺序

          MySQL采用从左往右,自上而下的顺序解析where子句。根据这个原理,应将过滤数据多的条件往前放,最快速度缩小结果集。

          相关实践学习
          如何在云端创建MySQL数据库
          开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
          全面了解阿里云能为你做什么
          阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
          相关文章
          |
          1天前
          |
          SQL 关系型数据库 MySQL
          MySQL慢查询优化、索引优化、以及表等优化详解
          本文详细介绍了MySQL优化方案,包括索引优化、SQL慢查询优化和数据库表优化,帮助提升数据库性能。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
          MySQL慢查询优化、索引优化、以及表等优化详解
          |
          6天前
          |
          缓存 监控 关系型数据库
          如何优化MySQL查询速度?
          如何优化MySQL查询速度?【10月更文挑战第31天】
          20 3
          |
          8天前
          |
          缓存 关系型数据库 MySQL
          如何优化 MySQL 数据库的性能?
          【10月更文挑战第28天】
          28 1
          |
          15天前
          |
          NoSQL 关系型数据库 MySQL
          MySQL与Redis协同作战:百万级数据统计优化实践
          【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
          46 9
          |
          15天前
          |
          NoSQL 关系型数据库 MySQL
          MySQL与Redis协同作战:优化百万数据查询的实战经验
          【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
          42 5
          |
          20天前
          |
          存储 关系型数据库 MySQL
          优化 MySQL 的锁机制以提高并发性能
          【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
          28 1
          |
          20天前
          |
          缓存 关系型数据库 MySQL
          一文彻底弄懂MySQL优化之深度分页
          【10月更文挑战第24天】本文深入探讨了 MySQL 深度分页的原理、常见问题及优化策略。首先解释了深度分页的概念及其带来的性能和资源问题。接着介绍了基于偏移量(OFFSET)和限制(LIMIT)以及基于游标的分页方法,并分析了它们的优缺点。最后,提出了多种优化策略,包括合理创建索引、优化查询语句和使用数据缓存,帮助提升分页查询的性能和系统稳定性。
          |
          23天前
          |
          NoSQL 关系型数据库 MySQL
          MySQL与Redis协同作战:百万数据量的优化实录
          【10月更文挑战第6天】 在现代互联网应用中,随着用户量的增加和业务逻辑的复杂化,数据量级迅速增长,这对后端数据库系统提出了严峻的挑战。尤其是当数据量达到百万级别时,传统的数据库解决方案往往会遇到性能瓶颈。本文将分享一次使用MySQL与Redis协同优化大规模数据统计的实战经验。
          92 3
          |
          23天前
          |
          NoSQL 关系型数据库 BI
          记录一次MySQL+Redis实现优化百万数据统计的方式
          【10月更文挑战第13天】 在处理百万级数据的统计时,传统的单体数据库往往力不从心,这时结合使用MySQL和Redis可以显著提升性能。以下是一次实际优化案例的详细记录。
          87 1
          |
          30天前
          |
          SQL 关系型数据库 MySQL
          在日常工作中怎么做MySQL优化的?
          在日常工作中怎么做MySQL优化的?

          推荐镜像

          更多
          下一篇
          无影云桌面