//

优化SQL语句的一般步骤

//

在MySQL中,SQL优化是很常见的一种需求,我自己这方面的经验也不是特别充足,在我自己的认知中,通常情况下,会通过下面的步骤去优化一个慢日志较多MySQL服务。

1、通过show global status命令查看当前执行最多的是哪些SQL动作。

例如Com_select指的是select的次数,Com_insert代表insert的次数,通常情况下:Com_insert,Com_select,Com_update和Com_delete用的最多。其中insert语句,如果是批量插入的话,只会累计1

上面的这几个参数是针对所有的存储引擎的,下面的是针对innodb存储引擎的:

innodb_rows_read select查询返回的行数;

innodb_rows_insert 执行insert操作返回的行数;

innodb_rows_update 执行update操作更新的行数;

innodb_rows_delete 执行delete操作删除的行数

通过这些参数,可以很快的确定当前MySQL主要是以更新为主还是以查询为主。

对于事务应用比较多的场景,可以通过Com_commit和Com_rollback来了解事务的提交和回滚情况。

2、通过pt-query-digest工具来分析MySQL的慢日志,其中慢日志的目录是slow_query_log_file,而慢日志的阈值是参数long_query_time控制的。

mysql> show variables like '%slow%file%';+---------------------+------------------------------------+| Variable_name       | Value                              |+---------------------+------------------------------------+| slow_query_log_file | /data/mysql_4306/log/slowquery.log |+---------------------+------------------------------------+1 row in set (0.00 sec)

mysql> show variables like '%long_query%';+-----------------+----------+| Variable_name   | Value    |+-----------------+----------+| long_query_time | 1.000000 |+-----------------+----------+1 row in set (0.00 sec)

pt-query-digest工具可以解析出来当前的慢日志的一个分析报告。具体用法,之前的文章介绍过,这里不再赘述。

3、通过explain或者desc命令来分析SQL的执行计划。

一般可以发现SQL是否使用了索引以及索引是否需要优化等信息。

4、通过profile命令来查看当前最主要的耗费时间的步骤。

mysql> select count(1) from t1;+----------+| count(1) |+----------+|        1 |+----------+1 row in set (0.11 sec)

mysql> show profiles;+----------+------------+-------------------------+| Query_ID | Duration   | Query                   |+----------+------------+-------------------------+|        1 | 0.00123300 | show databases          ||        2 | 0.00016775 | SELECT DATABASE()       ||        3 | 0.00092900 | show databases          ||        4 | 0.00122325 | show tables             ||        5 | 0.00134250 | show tables             ||        6 | 0.11396400 | select count(1) from t1 |+----------+------------+-------------------------+6 rows in set, 1 warning (0.00 sec)

mysql> show profile for query 6; +--------------------------------+----------+| Status                         | Duration |+--------------------------------+----------+| starting                       | 0.000089 || Executing hook on transaction  | 0.000013 || starting                       | 0.000011 || checking permissions           | 0.000008 || Opening tables                 | 0.000040 || init                           | 0.000015 || System lock                    | 0.000015 || optimizing                     | 0.000007 || statistics                     | 0.000024 || preparing                      | 0.000029 || executing                      | 0.113622 || end                            | 0.000011 || query end                      | 0.000006 || waiting for handler commit     | 0.000014 || closing tables                 | 0.000013 || freeing items                  | 0.000022 || cleaning up                    | 0.000027 |+--------------------------------+----------+17 rows in set, 1 warning (0.00 sec)

上面的分析不难看出,这条SQL大部分时间都浪费在了executing上面,为了更清晰的看到结果,可以通过information_schema表对上面的结果进行排序:

mysql> select state,sum(duration) as total_r , round(100*sum(duration)/(select sum(duration) from information_schema.profiling where query_id=6),2) as pct_r,count(*) as calls,sum(duration)/count(*) as 'R/Call' from information_schema.profiling where query_id group by state order by total_r desc;+--------------------------------+----------+--------+-------+--------------+| state                          | total_r  | pct_r  | calls | R/Call       |+--------------------------------+----------+--------+-------+--------------+| executing                      | 0.114058 | 100.08 |     6 | 0.0190096667 || Opening tables                 | 0.001226 |   1.08 |     6 | 0.0002043333 || checking permissions           | 0.000852 |   0.75 |    56 | 0.0000152143 || starting                       | 0.000692 |   0.61 |     8 | 0.0000865000 || Creating tmp table             | 0.000524 |   0.46 |     4 | 0.0001310000 || init                           | 0.000410 |   0.36 |     6 | 0.0000683333 || statistics                     | 0.000361 |   0.32 |     5 | 0.0000722000 || preparing                      | 0.000165 |   0.14 |     5 | 0.0000330000 || freeing items                  | 0.000138 |   0.12 |     7 | 0.0000197143 || cleaning up                    | 0.000108 |   0.09 |     7 | 0.0000154286 || optimizing                     | 0.000092 |   0.08 |     6 | 0.0000153333 || waiting for handler commit     | 0.000084 |   0.07 |     9 | 0.0000093333 || System lock                    | 0.000079 |   0.07 |     5 | 0.0000158000 || closing tables                 | 0.000067 |   0.06 |     6 | 0.0000111667 || query end                      | 0.000039 |   0.03 |     6 | 0.0000065000 || end                            | 0.000035 |   0.03 |     6 | 0.0000058333 || removing tmp table             | 0.000018 |   0.02 |     4 | 0.0000045000 || Executing hook on transaction  | 0.000013 |   0.01 |     1 | 0.0000130000 |+--------------------------------+----------+--------+-------+--------------+18 rows in set, 2 warnings (0.00 sec)

当然,profile还支持查看all、cpu、block io、content switch、page faults等明细类型,例如查看上述语句在CPU资源上消耗的时间:

show profile cpu  for query 6;

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

这块儿后续找一篇文章展开说说。

基本上以上的步骤,可以足够我们定位MySQL服务慢的问题,后续根据实际问题,来进行相应的处理即可。

有帮助的话还希望点下再看哈

sql in语句优化_优化SQL语句的一般步骤相关推荐

  1. sql 双分区查询_优化案例 | 分区表场景下的SQL优化

    导读 有个表做了分区,每天一个分区. 该表上有个查询,经常只查询表中某一天数据,但每次都几乎要扫描整个分区的所有数据,有什么办法进行优化吗? 一.待优化场景 有一个大表,每天产生的数据量约100万,所 ...

  2. mysql报表统计 优化_关于SQL调优与报表的性能优化

    前一段时间做了某产品实时统计的报表,这周在对报表性能进行优化. 其中逐步积累了一些优化经验,总结一下记录下来,欢迎大家一起探讨. 本文仅限于探讨单个数据库的查询sql及统计报表调优,不涉及分布式数据库 ...

  3. java数据库查询语句题_数据库查询语句面试

    Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题 ...

  4. mysql查询数据库创建语句是_查询数据库语句

    一.Select语句:67页 select语句除了可以查看数据库中的表格和视图的信息外,还可以查看SQL Server的系统信息.复制.创建数据表,其查询功能强大,是SQL语言的灵魂语句,也是SQL中 ...

  5. sql 触发器未触发_学习SQL:SQL触发器

    sql 触发器未触发 SQL Triggers are another powerful database object we have at our disposal. In previous ar ...

  6. sql子查询示例_学习SQL:SQL查询示例

    sql子查询示例 In the previous article we've practiced SQL, and today, we'll continue with a few more SQL ...

  7. sql server的搜索_在SQL Server中进行全文本搜索

    sql server的搜索 介绍 (Introduction) In most cases, we will use clustered and non-clustered indexes to he ...

  8. 复杂sql 查询编写方法_学习SQL:如何编写复杂的SELECT查询

    复杂sql 查询编写方法 In my career, I've heard many times, things like "How to write a complex SELECT qu ...

  9. 学习sql注入:猜测数据库_学习SQL:删除和更新数据SQL最佳实践

    学习sql注入:猜测数据库 Deleting and updating data is very common, but if performed without taking care, which ...

  10. mysql sql注入很常用_常见sql注入的类型

    这里只讲解sql注入漏洞的基本类型,代码分析将放在另外一篇帖子讲解 目录 最基础的注入-union注入攻击 Boolean注入攻击-布尔盲注 报错注入攻击 时间注入攻击-时间盲注 堆叠查询注入攻击 二 ...

最新文章

  1. OpenGL渲染流水中的处理步骤
  2. c 语言怎么编译 .dll,将你的 C 语言代码编译成 .NET
  3. SpringBoot 集成 clickhouse + mybatis-plus 配置及使用问题说明(含建表语句、demo源码、测试说明)
  4. 空间句法软件_【特训营报名】空间句法理论与实践应用(第二期更新版)丨城市数据派...
  5. sparkshelljarlib_Spark应用程序第三方jar文件依赖解决方案
  6. 用Java中的抽象类扩展抽象类
  7. ORACLE——ROWNUM解析(使用ROWNUM大于条件,无法得到任何查询结果)
  8. C#泛型学习实例(简单易懂)
  9. linux下运行exe程序之wine的使用与安装
  10. Delphi 7 在Win 7 下的安装使用
  11. 华为云虚拟主机的防火墙设置
  12. android 读取本地超大图片
  13. 翟菜花:她经济的营销攻坚战,4C的用户导向才是破局之法
  14. Android 获取DNS
  15. 国内外汽车道路行驶工况数据
  16. Windows远程桌面连接Mac OS X
  17. 【转】经典的劝酒令和挡酒词
  18. WPF嵌入技术1_嵌入WPF到cad(MFC,win32窗体),Win32API嵌入WPF位置跳走的解决方案
  19. unity 双屏,多屏幕显示
  20. 开源 iOS 项目分类索引大全 - 待整理

热门文章

  1. 一次历时两周的实习生笔试
  2. 了解轻量级的移动开发Javascript类库- Zepto.js
  3. Linux环境进程间通信(一)管道和FIFO
  4. 在 Nvidia 显卡下设置装备铺排双浮现器
  5. 查询 加载时间过长添加提示信息
  6. WF学习系列之四:顺序工作流控制台应用程序模板介绍
  7. Java线程池如何体现自己的用途
  8. RabbitMQ 实现RPC
  9. 前端移动App开发环境搭建
  10. try{return} finally