一、优化SQL语句的一般步骤

1.1 通过show status命令了解各种SQL的执行频率

Mysql客户端连接成功后,通过

show [session|global] status

命令可以提供服务器状态信息。show [session|global] status可以根据需要加上参数"session"或者"global"来显示seesion级(当前连接)的统计结果和global级(自数据库上次启动至今)的统计结果。如果不写,默认使用的参数时"session"。

例如:显示当前session中所有统计参数的值:

mysql> show status like 'Com_%';

Com_xxx表示每个xxx语句执行的次数。

  • Com_select:执行select操作的次数,一次查询之累加1.
  • Com_insert:执行insert操作的次数,对于批量插入insert操作,只累加一次。
  • Com_update:执行update操作的次数。
  • Com_delete:执行delete操作的次数。

    上面这些参数对于所有存储引擎的表操作都会进行累计。下面这几个参数只是针对InnoDB存储引擎的,累加的算法也略有不同。
  • Innodb_rows_read:select查询返回的行数。
  • Innodb_rows_inserted:执行insert操作插入的行数。
  • Innodb_rows_updated:执行update操作更新的行数。
  • Innodb_rows_deleted:执行delete操作删除的行数。

    通过以上参数,可以很容易了解到当前数据库的应用是以插入更新为主还是以查询操作为主,以及各种类型的SQK大致的执行比例是多少。

    对于更新操作的计数,是对执行次数的计数,不论提交还是回滚都会进行累加。

对于事务型的应用,通过Com_commit和Com_rollback可以了解事物提交和回滚的情况,对于回滚操作频繁的数据库,可能意味着应用编写存在问题。

此外,以下几个参数便于用户了解数据库的基本情况:

  • Connections:试图连接Mysql服务器的次数。
  • Uptime:服务器工作时间。
  • Slow_queries:慢查询的次数。

1.2 定位执行效率较低的SQL语句

  • 通过慢查询日志定位那些执行效率较低的SQL语句,用-log-slow-queries[=file_name]选项启动时, mysqld写一个包含所有执行时间超过long_ query_ _time秒的SQL语句的日志文件。
  • 慢查询日志在查询结束以后才记录,所以在应用反映执行效率出现问题的时候查询慢查询日志并不能定位问题,可以使用show processlist命令查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看SQL的执行情况,同时对一些锁表操作进行优化。

1.3 通过explain分析低效sql的执行计划

通过以上步骤查询到效率低的SQL语句后,可以通过explain或者desc命令获取mysql如何执行select 语句的信息,包括在select语句执行过程中表如何连接和连接的顺序。

比如想统计某个email为租赁电影拷贝所支付的总金额,需要关联客户表customer和付款表payment,并且对付款金额amount字段做求和sum操作:

对每个列简单地进行一下说明。

  • select_type:表示select的类型,常见的取值有simple(简单表,即不使用表连接或者子查询)、Primary(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个SELECT)等。
  • table:输出结果集的表。
  • type:表示mysql在表中找到所需行的方式,或者叫访问类型。常见类型有:all、index、range、ref、eq_ref、const,system、null

    从左到右,性能由最差到最好。
  1. type=all,全表扫描,mysql遍历全表来找到匹配的行:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mZfmqdCP-1583484754266)(https://www.showdoc.cc/server/api/common/visitfile/sign/8531f1a04f70def98d9abc57c3e56f12?showdoc=.jpg)]
  2. type=index,索引全扫描,mysql遍历整个索引来查询匹配的行:

  3. type=range,索引范围扫描,常见于<、<=、>、>=、between等操作符:



4. type=ref,使用非唯一索引扫描或唯一索引的前缀扫描,返回匹配某个单独值的记录行,例如:



索引idx_fk_customer_id是非唯一索引,查询条件为等值查询条件customer_id=35,所以扫描索引的类型为ref。ref还经常出现在join操作中:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c4GLg27n-1583484754268)(https://www.showdoc.cc/server/api/common/visitfile/sign/60851deac070f774c1b6453cb00b96bc?showdoc=.jpg)]

5. type=eq_ref,类似ref,区别就在使用的索引时唯一索引,对于每个索引键值,表中只有一条记录匹配。即多表连接中使用primary key或者unique index作为关联条件。



6. type=const/system,单表中最多有一个匹配行,查询起来非常迅速,所以这个匹配行中的其他列的值被优化器在当前查询中当作常量来处理,例如,根据主键primary key或唯一索引unique index进行的查询。

构造一个查询:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3oJS5ABu-1583484754268)(https://www.showdoc.cc/server/api/common/visitfile/sign/5c67476c5ae91a49f120edf0eae4f23b?showdoc=.jpg)]



通过唯一索引uk_email访问的时候,类型为const,而从我们构造的仅有一条记录的a表中检索时,类型type就为system。

7. type=null,mysql不用访问表或者索引,直接就能得到结果,例如:

类型type还有其他值,如ref_or_null、index_merge(索引合并优化)、unique_subquery(in的后面是一个查询主键字段的子查询)、index_subquery(与unique_subquery类似,区别在于in的后面是查询非唯一索引字段的子查询)等。

  • possible_keys:表示查询时可能使用的索引。
  • key:表示实际使用的索引。
  • key_len:使用到索引字段的长度。
  • rows:扫描行的数量。
  • Extra:执行情况的说明和描述,包含不适合在其他列中显示但是对执行计划非常重要的额外信息。

1.4 通过show profile分析sql

通过have_profiling参数,能够看到当前mysql是否支持profile:

mysql> select @@hava_profiling;

默认profiling是关闭的,可通过set语句在Session级别开启profiling:

mysql> select @@profiling;

mysql> set profiling=1;

通过profile,能清楚地了解sql执行的过程。

在一个InnoDB引擎的付款表payment上,执行一个count(*)查询:

mysql> select count(*) from payment;

执行完毕后,通过show profiles语句,查看当前SQL的Query ID:

通过show profile for query语句能够看到执行过程中线程的每个状态和消耗的时间:

Sending data状态表示mysql线程开始访问数据行并把结果返回给客户端,而不仅仅是返回结果给客户端。由于在Sending data状态下,mysql线程往往需要做大量的磁盘读取操作,所以经常是整个查询中最耗时的状态。

在获取到最消耗时间的线程状态后,mysql支持进一步选择all、cpu、block io、context switch、page faults等明细类型来查mysql在使用什么资源上耗费了过高的时间。

例如:选择查询CPU的耗费时间:

mysql> show profile cpu for query 4;

Sending data状态下,时间消耗主要在CPU上了。

1.5 通过trace分析优化器如何选择执行计划

通过trace文件能够进一步了解为什么优化器选择A执行计划而不选择B执行计划。

使用方式:首先打开trace,设置格式为JSON,设置trace最大能够使用的内存大小,避免解析过程中因为默认内存过小而不能够完全显示。

mysql> set optimizer_trace="enabled=on",end_markers_in_json=on;

mysql> set optimizer_trace_max_size=1000000;

执行想做trace的SQL语句:

最后检查Information_schema.optimizer_trace就可以知道mysql是如何执行SQL的:

mysql> select * from information_schema.optimizer_trace \G

1.6 确定问题并采取相应的优化措施

MySql(五)SQL优化-优化SQL语句的一般步骤的更多相关文章

  1. MySQL基础操作&&常用的SQL技巧&&SQL语句优化

    基础操作     一:MySQL基础操作         1:MySQL表复制             复制表结构 + 复制表数据             create table t3 like t ...

  2. mysql优化SQL语句的一般步骤及常用方法

    一.优化SQL语句的一般步骤 1. 通过show status命令了解各种SQL的执行频率 mysqladmin extended-status 或: show [session|global]sta ...

  3. mysql性能优化之数据库级别优化--优化sql语句

    一  优化SELECT语句 1.1 WHERE子句优化 本文暂时只讨论可以处理WHERE子句的优化,下面的一些实例使用SELECT语句,但是相同的优化同样适用DELETE和UPDATE语句中的WHER ...

  4. 浅谈mysql配置优化和sql语句优化【转】

    做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...

  5. mysql优化和sql语句优化总结

    mysql性能优化 1. EXPLAIN 你的 SELECT 查询.使用 EXPLAIN 关键字可以让你知道MySQL是如何处理你的SQL语句的.这可以帮你分析你的查询语句或是表结构的性能瓶颈. 2. ...

  6. mysql优化-数据库优化、SQL优化

    我有一张表w1000,里面有1000万条数据,这张表结构如下:CREATE TABLE `w1000` ( `id` varchar(36) NOT NULL, `name` varchar(10) ...

  7. SQL高级优化(六)之MySQL索引

    一.索引概述 1. 索引的优点 ​ 为什么要创建索引?这是因为,创建索引可以大大提高系统的查询性能.如果不使用索引,查询时从第一行开始查询.如果使用了索引,所以就可以更加快速的找到希望的数据. 第一. ...

  8. [MySQL] 常用SQL的优化--18.4

    这里介绍下,Insert.Group By等SQL语句的优化方法: 1.大批量数据插入 当load命令导入数据的时候,可以进行适当的设置提高导入速度. 1.1 对于MyISAM表,可以先禁用非唯一索引 ...

  9. MySQL数据库SQL层级优化

    本篇主涉及MySQL SQL Statements层面的优化. 首先,推荐一个链接为万物之始:http://dev.mysql.com/doc/refman/5.0/en/optimization.h ...

随机推荐

  1. Redis如何做内存优化?

    1.缩减键值对象 缩减键(key)和值(value)的长度, key长度:如在设计键时,在完整描述业务情况下,键值越短越好. value长度:值对象缩减比较复杂,常见需求是把业务对象序列化成二进制数组 ...

  2. MongoDb学习(四)--Repository

    在学习这个的时候.关于Repository的映射.在备注xml的时候出现了错误. 错误有点坑.以后写的时候注意一点,在学习的时候.用的mongo的jar包版本比较低. 然而本机操作的时候,用的是最新版 ...

  3. 【Azure Application Insights】在Azure Function中启用Application Insights后,如何配置不输出某些日志到AI 的Trace中

    问题描述 基于.NET Core的Function App如果配置了Application Insights之后,每有一个函数被执行,则在Application Insights中的Logs中的tra ...

  4. 每日一个linux命令6 -- rmdir

    rmdir doc 如果doc为空目录则删除,否则无法删除. rmdir -p test2/test3 递归删除空目录,首先判断test3,如果test3为空,则删除test3,此时判断test2,如 ...

  5. Spring Cloud Gateway 跨域 CORS 配置方式实现

    网上找了一堆文章全是说这样写无效 globalcors: cors-configurations: '[/**]': allowCredentials: true allowedOriginPatte ...

  6. Linux find 命令的初步实现(C++)

    Implement a myfind command following the find command in UNIX operating system. The myfind command s ...

  7. 通过JS逆向ProtoBuf 反反爬思路分享

    前言 本文意在记录,在爬虫过程中,我首次遇到Protobuf时的一系列问题和解决问题的思路. 文章编写遵循当时工作的思路,优点:非常详细,缺点:文字冗长,描述不准确 protobuf用在前后端传输,在 ...

  8. 【Spring】Spring的事务管理 - 2、声明式事务管理(实现基于XML、Annotation的方式。)

    声明式事务管理 文章目录 声明式事务管理 基于XML方式的声明式事务 基于Annotation方式的声明式事务 简单记录 - 简单记录-Java EE企业级应用开发教程(Spring+Spring M ...

  9. 【Spring】Spring中的Bean - 2、Baen的实例化 (构造器、静态工厂、实例工厂)

    Bean的实例化 文章目录 Bean的实例化 构造器实例化 静态工厂方式实例化 实例工厂方式实例化 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-S ...

  10. [APUE] 文件 I/O

    文件操作相关 API:open, read, write, lseek, close. 多进程共享文件的相关 API:dup, dup2, fcntl, sync, fsync, ioctl. 文件操 ...