Mysql优化手册

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 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子句。根据这个原理,应将过滤数据多的条件往前放,最快速度缩小结果集。

          相关实践学习
          每个IT人都想学的“Web应用上云经典架构”实战
          本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
          MySQL数据库入门学习
          本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
          相关文章
          |
          3月前
          |
          SQL 缓存 关系型数据库
          MySQL 慢查询是怎样优化的
          本文深入解析了MySQL查询速度变慢的原因及优化策略,涵盖查询缓存、执行流程、SQL优化、执行计划分析(如EXPLAIN)、查询状态查看等内容,帮助开发者快速定位并解决慢查询问题。
          149 0
          |
          1月前
          |
          缓存 关系型数据库 MySQL
          降低MySQL高CPU使用率的优化策略。
          通过上述方法不断地迭代改进,在实际操作中需要根据具体场景做出相对合理判断。每一步改进都需谨慎评估其变动可能导致其他方面问题,在做任何变动前建议先在测试环境验证其效果后再部署到生产环境中去。
          76 6
          |
          2月前
          |
          存储 SQL 关系型数据库
          MySQL 核心知识与索引优化全解析
          本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
          |
          7月前
          |
          SQL 关系型数据库 MySQL
          MySQL进阶突击系列(07) 她气鼓鼓递来一条SQL | 怎么看执行计划、SQL怎么优化?
          在日常研发工作当中,系统性能优化,从大的方面来看主要涉及基础平台优化、业务系统性能优化、数据库优化。面对数据库优化,除了DBA在集群性能、服务器调优需要投入精力,我们研发需要负责业务SQL执行优化。当业务数据量达到一定规模后,SQL执行效率可能就会出现瓶颈,影响系统业务响应。掌握如何判断SQL执行慢、以及如何分析SQL执行计划、优化SQL的技能,在工作中解决SQL性能问题显得非常关键。
          |
          2月前
          |
          存储 SQL 关系型数据库
          MySQL 动态分区管理:自动化与优化实践
          本文介绍了如何利用 MySQL 的存储过程与事件调度器实现动态分区管理,自动化应对数据增长,提升查询性能与数据管理效率,并详细解析了分区创建、冲突避免及实际应用中的关键注意事项。
          119 0
          |
          4月前
          |
          存储 SQL 关系型数据库
          京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
          京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
          京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
          |
          9月前
          |
          SQL 关系型数据库 MySQL
          深入解析MySQL的EXPLAIN:指标详解与索引优化
          MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
          1788 10
          |
          6月前
          |
          存储 关系型数据库 MySQL
          MySQL细节优化:关闭大小写敏感功能的方法。
          通过这种方法,你就可以成功关闭 MySQL 的大小写敏感功能,让你的数据库操作更加便捷。
          466 19
          |
          7月前
          |
          SQL 关系型数据库 MySQL
          基于SQL Server / MySQL进行百万条数据过滤优化方案
          对百万级别数据进行高效过滤查询,需要综合使用索引、查询优化、表分区、统计信息和视图等技术手段。通过合理的数据库设计和查询优化,可以显著提升查询性能,确保系统的高效稳定运行。
          254 9
          |
          7月前
          |
          关系型数据库 MySQL 数据库
          从MySQL优化到脑力健康:技术人与效率的双重提升
          聊到效率这个事,大家应该都挺有感触的吧。 不管是技术优化还是个人状态调整,怎么能更快、更省力地完成事情,都是我们每天要琢磨的事。
          159 23

          推荐镜像

          更多