一、优化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. 如何在K8S中优雅的使用私有镜像库 (Docker版)

    前言 在企业落地 K8S 的过程中,私有镜像库 (专用镜像库) 必不可少,特别是在 Docker Hub 开始对免费用户限流之后, 越发的体现了搭建私有镜像库的重要性. 私有镜像库不但可以加速镜像的拉 ...

  2. JavaDailyReports10_09

    ***************************** 1.2.2 布局管理器 BorderLayout 把容器的布局分为东西南北中五个部位,默认是中间,平铺占满! 1 package awt; ...

  3. Mysql大概1700W大表删除1000W左右数据,发现数据大小和索引大小并没有减少思考

    MySQL删除操作其实是假删除 因为近期在重构优化一个业务的时候 发现有一张表(send_log)数据量将近1700W 左右  占用数据大小17G,索引18G左右  而我们的核心应用在使用的时候 会去 ...

  4. tail常用命令总结

    tail命令作用: tail命令用途是依照要求将指定的文件的最后部分输出到标准设备,通常是终端,通俗讲来,就是把某个档案文件的最后几行显示到终端上,假设该档案有更新,tail会自己主动刷新,确保你看到 ...

  5. CentOS-8.3.2011-x86_64 配置网络环境的几个方案以及问题处理方法

    1. 在安装前的环境配置中配置网络 可以通过 NETWORK & HOST NAME 进行网络配置, 推介通过这里便捷设置. 如果在安装的 CentOS 之前的配置选项中没有进行用户和网络的配 ...

  6. 浅谈localStorage的使用场景和优劣势,以及sessionStorage和cookie

    一.localStorage,sessionStorage,cookie的简单介绍 localStorage:仅在客户端存储不参与服务器通信,存储大小一般为5M,如果不是人为清除,那么即使是关闭浏览器 ...

  7. 搭乘“AI大数据”快车,肌肤管家,助力美业数字化发展

    经过疫情的发酵,加速推动各行各业进入数据时代的步伐.美业,一个通过自身技术.产品让用户变美的行业,在AI大数据的加持下表现尤为突出. 对于美妆护肤企业来说,一边是进入存量市场,一边是疫后的复苏期,一边 ...

  8. MySQL select 查询之分组和过滤

    SELECT 语法 SELECT [ALL | DISTINCT] {* | table.* | [table.field1[as alias1][,table.field2[as alias2]][ ...

  9. 【Linux】配置ssh留下的一些思考和大坑解决办法

    今天传包突然有问题,结果发现是ssh出现了问题,密钥也在里面,都是正常的,但是还有什么问题呢? 后来总结下需要注意点: 1.最开始你要检查.ssh/  这个文件夹的权限,看下权限是否为700或者为75 ...

  10. 【Linux】如何查看命令来源于哪个包

    Debian:(Ubuntu等) 先安装apt-file sudo apt-get install -y apt-file apt-file update 查询命令:(已查询ifconfig为例) r ...