慢日志分析流程如下:
【1】观察(至少跑一天),看看生产慢 SQL 情况。
【2】开启慢查询日志,设置阈值,比如对超过5秒的 SQL 语句进行抓取。
【3】explain+慢 SQL 分析。
【4】show profile 查询慢 SQL 在 MySQL 中的执行细节和生命周期情况。
【5】运维经理 or DBA 对数据库参数进行调优。

一、查询优化


【1】永远小表驱动大表(存在连接问题),类似嵌套循环 Nested Loop。例如:当 B表的数据集小于 A表时,用 In 优于 Exist。因为先执行B表在执行A表。

SELECT * FROM A WHERE ID IN (SELECT ID FROM B)

当 A表的数据集小于 B表的时候,用 Existsl 优于 In。因为先执行 A表在执行 B表。

SELECT * FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.ID = A.ID)

该语法可以理解为将主查询的数据,放到子查询中做条件验证,根据验证的结果(TURE OR FLASE)来解决主查询的数据结果是否保留。
【2】order by 关键字优化:尽量使用 Index 方式进行排序,效率高因为 MySQL 是通过扫描索引进行排序,避免使用fileSort(文件排序) 方式排序。使用 index 的前提:
   ■  order by 语句使用了索引最左前缀规则;
   ■  where 子句与 order by 子句条件列组合满足索引最左列;
filesort 有两种算法如果不在索引列上,MySQL就要启动双路排序单路排序。
   ■  双路排序:MySQL4.1 之前使用的是双路排序,字面意思就是两次扫面磁盘,最终得到数据。读取指针和 order by 所含的列,对他们进行排序,然后扫描已经排好的列表,按照列表中排好的值重新从列表中读取对应的数据输出。一句话,从磁盘读取排序字段,在 buffer 进行排序,在从磁盘读取其他字段。
   ■  单路排序从磁盘读取查询所需要的列,按照 order by 列在 buffer 上对它们进行排序,然后扫描排序中的列输出。它的效率快,避免了二次读取数据。
【结论及引申出的问题】:单路总体上优于双路算法。但是单路算法有问题:当获取的数据的总大小 > sort_buffer 的容量时,就需要多次获取排序(多路),反而不如双路排序高效。
【优化策略】①、增大 sort_buffer_size 参数的设置。②、增大 max_length_for_sort_data(因为单路排序为将要排序的每一行创建了固定的缓冲区,varchar 列的最大长度是 max_length_for_sort_data 规定的值,而不是排序数据的实际大小)参数的设置。③、当使用 order by 时忌讳使用 select * 查询。
总结
【3】group by 关键字优化:①、group by 实质是先排序再分组,遵循最左前缀法则;
   ②、无法使用索引列的时候也要增大 sort_buffer_size 参数和 max_length_for_sort_size 参数设置;
   ③、where 高于 having 能写在 where 限定条件里面的就不要写在 having 限定中;

二、慢查询日志


【1】what 慢查询日志:MySQL 的慢查询日志是 MySQL 提供的一种日志记录,它用来记录在 MySQL 中相应时间超过阈值的语句,具体指运行时间超过 long_query_time 值得 SQL,则会被记录在慢查询日志中。默认值为:10s,通常设置为 2s或 5s;
【2】默认情况下:MySQL 数据库没有开启慢查询日志,需要手动开启。当然,如果不是调优需要的话,一般不建议开启,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件。

show VARIABLES like '%slow_query_log%';

开启:set global slow_query_log = 1; 只对当前数据库生效,如果重启 MySQL 则会失效。如果要永久生效,就必须设置配置文件 my.cnf。在 [mysqlid] 下添加:

slow_query_log=1;
slow_query_log_file=/var/lib/mysql/xxx-slow.log

查看设置的阈值时间,在 MySQL 中判断查询时间是否大于阈值时间,大于则记录。

show VARIABLES like '%long_query_time%';

设置阈值时间,修改后需要重新连接或者重开会话才生效。

set global long_query_time=2

可以通过 select sleep(4),进行测试,日志文件内容如下:

查询当前系统有多少条慢查询记录

show global status like '%slow_queries %';

如果想永久设置 time 在[mysqlid]下:

long_query_time=3;
log_output=FILE;

【3】MySQL 分析工具 mysqldumpslow:查看 sql 的帮助信息。常用命令如下:
   ①、得到返回记录集最多的10条记录:mysqldumpslow -s r -t 10 /var/lib/mysql/xxx.log
   ②、得到访问次数最多的10个SQL:mysqldumpslow -s c -t 10 /var/lib/mysql/xxx.log
   ③、得到按照时间排序的前10条含有左连接的查询语句:mysqldumpslow -s t -t 10 -g 'left join' /var/lib/mysql/xxx.log
   ④、建议使用这些命令的时候结合|和more使用,否则会出现爆屏的情况:mysqldumpslow -s r -t 10 /var/lib/mysql/xxx.log | more

三、批量数据脚本


函数与存储过程的区别:函数有且一个返回值,存储过程可以有0至n个返回值。

【1】设置参数 log_bin_trust_function_creators(当二进制日志启用后,这个变量就会启用。它控制是否可以信任存储函数创建者,不会创建写入二进制日志引起不安全事件的存储函数。如果设置为0(默认值),用户不得创建或修改存储函数,除非它们具有除 CREATE ROUTINE 或 ALTER ROUTINE特权之外的 SUPER 权限。 设置为0还强制使用 DETERMINISTIC 特性或READS SQL DATA或NO SQL特性声明函数的限制。 如果变量设置为1,MySQL不会对创建存储函数实施这些限制。 此变量也适用于触发器的创建)创建函数的时候如果报错:this function has none of DETERMINISTIC......

由于开启慢日志查询也开启了 bin-log,就必须为 function 指定一个参数。查看是否开启:如果未开启则开启如下,如果要长期设置和上面配置一样在配置文件中配置。

show variables like '%log_bin_trust_function_creators%';
set global log_bin_trust_function_creators=1;

【2】创建函数保证每条数据都不同:①、返回随机字符串:

 1 DELIMITER $$
2 CREATE FUNCTION rand_string(n INT) RETURNS(255)
3 BEGIN
4 DECLARE chars_str VARCHAR(100) DEFAULT 'QWERTYUIOPLKJHGFDSAZXCVBNMmnbvcxzasdfghjklpoiuytrewq';
5 DECLARE return_str DEFALUT '';
6 DECLARE i INT DEFALUT 0;
7 WHILE i<n DO
8 SET return_str = CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));
9 SET i=i+1;
10 END WHILE;
11 RETURN retrun_str;
12 END $$

删除function:drop function xxx;

②、创建存储过程:

 1 DELIMITER $$
2 CREATE PROCEDURE insert_emp(IN start INT(10),IN max_num INT(10))
3 BEGIN
4 DECALRE i INT DEFAULT 0;
5 SET autocommit = 0;
6 REPEAT
7 SET i = i+1;
8 INSERT INTO emp() VALUES();
9 UNIT i = max_num
10 END REPEAT;
11 COMMIT
12 END $$

③、调用存储过程

CALL insert_emp(100,10);

四、Show Profile


是 MySQL 提供可以用来分析当前会话中语句执行的资源消耗情况。可以用于 SQL 的调优的测量。默认是关闭状态,并保存最近15次的运行结果。

分析步骤
  ■  是否支持,看看当前 MySQL 的版本是否支持。show variables like 'profiling'
        ■  打开:set profiling=on;
       ■  运行SQL;
  ■  查看结果:show profiles
       ■  诊断SQL:show profiles cpu,block io for query id号
    

show profile 的常用查询参数:① ALL:显示所有的开销信息。
② BLOCK IO:显示块IO开销。
③ CONTEXT SWITCHES:上下文切换开销。
④ CPU:显示CPU开销信息。
⑤ IPC:显示发送和接收开销信息。
⑥ MEMORY:显示内存开销信息。
⑦ PAGE FAULTS:显示页面错误开销信息。
⑧ SOURCE:显示和 Source_function,Source_file,Source_line相关的开销信息。
⑨ SWAPS:显示交换次数开销信息。
结论①、converting HEAP to MYISAM 查询结果太大,内存不够用了往磁盘上搬了。②、Creating tmp table 创建临时表。③、Copying to tmp table on disk 把内存中临时表复制到磁盘。④、locked。
Explain 语句分析链接

五、全局查询日志:(永远不要在生产环境开启此功能)


【1】配置启用:my.cnf 配置文件中。

1 #开启
2 general_log=1
3 #记录日志文件路径
4 general_log_file=/path/logfile
5 #输出格式
6 log_output=FILE

【2】编码:命令:set global general_log=1;set global log_output='TABLE';之后编写的 SQL 语句,将被记录与 MySQL 库中的 general_log 表。查看命令:select * from mysql.general_log;

MySQL 高级查询截取分析的更多相关文章

  1. MySQL高级-查询截取分析

    一.如何分析 1.观察.至少跑1天,看看生产的慢SQL情况. 2.开启慢查询日志,设置阙值比如超过5秒钟的就是慢SQL,并将它抓取出来. 3.explain + 慢SQL分析 4.show profi ...

  2. MySQL高级学习笔记(五):查询截取分析

    文章目录 慢查询日志 是什么 怎么玩 说明 查看是否开启及如何开启 默认 开启 那么开启了慢查询日志后,什么样的SQL才会记录到慢查询日志里面呢? Case 配置版 日志分析工具mysqldumpsl ...

  3. 第四章 MySQL高级查询(二)

    第四章 MySQL高级查询(二) 一.EXISTS子查询 在执行create 或drop语句之前,可以使用exists语句判断该数据库对像是否存在,返回值是true或false.除此之外,exists ...

  4. MySQL 慢查询日志分析及可视化结果

    MySQL 慢查询日志分析及可视化结果 MySQL 慢查询日志分析 pt-query-digest分析慢查询日志 pt-query-digest --report slow.log 报告最近半个小时的 ...

  5. 第三章 MySQL高级查询(一)

    第三章 MySQL高级查询(一) 一.SQL语言的四个分类 1.       DML(Data Manipulation Language)(数据操作语言):用来插入,修改和删除表中的数据,如INSE ...

  6. MySQL 高级查询操作

    目录 MySQL 高级查询操作 一.预告 二.简单查询 三.显示筛选 四.存储过程 五.查询语句 1.作为变量 2.函数调用 3.写入数据表 备注 附表一 附表二 相关文献 博客提示 MySQL 高级 ...

  7. python进阶09 MySQL高级查询

    python进阶09 MySQL高级查询 一.筛选条件 # 比较运算符 # 等于:= 不等于:!= 或<> 大于:> 小于:< 大于等于>= 小于等于:<= #空: ...

  8. MySQL高级查询与编程作业目录 (作业笔记)

    MySQL高级查询与编程笔记 • [目录] 第1章 数据库设计原理与实战 >>> 第2章 数据定义和操作 >>> 2.1.4 使用 DDL 语句分别创建仓库表.供应 ...

  9. MySQL高级查询与编程笔记 • 【目录】

    章节 内容 实践练习 MySQL高级查询与编程作业目录(作业笔记) 第1章 MySQL高级查询与编程笔记 • [第1章 数据库设计原理与实战] 第2章 MySQL高级查询与编程笔记 • [第2章 数据 ...

  10. MySQL高级第三章——查询截取分析

    一.查询分析 1.永远小表驱动大表 使用小的数据集驱动大的数据集. //复习 EXISTS 的知识:SELECT ... FROM tb WHERE EXISTS (subquery) 是因为前后数据 ...

随机推荐

  1. python中列表,字典,字符串常用操作

    1. 列表操作 分类 关键字 / 函数 / 方法 说明 增加 列表.append(值) 在末尾追加值   列表.insert(索引, 值) 在指定位置插入值, 超过索引会追加值   列表.extend ...

  2. linux清除日志和文件缓存

    1.查找大文件,从根目录 find / -type f -size +800M 2.查看磁盘挂载情况及挂载目录 df -lh 3.查看内存使用情况 free -m 4.清除缓存 echo 3 > ...

  3. lvds接口

    1.lvds就是差分信号接口,tft-lcd屏幕,一种常用的接口. 2.有3种标准,18bit, 24bit(JEIDA) 与 24bit(VESA) 详细看https://www.topwaydis ...

  4. bquote

    在Linux环境下,按"·"(1左边的按钮)会进入bquote模式 退出方法 按 Ctrl + C 其它(待补充)

  5. Redis 集群模式的安装与配置【源码安装redis-7.0.5】

    Redis最新版下载地址:http://download.redis.io/releases/redis-7.0.5.tar.gz 步骤如下: 1)wget http://download.redis ...

  6. scrollToFirstError失效解决方法

    ant design 使用 设置scrollToFirstError = true,表单验证失败后却没有滚动到第一个错误字段 解决方法: 在button按钮中加入 html-type = 'submi ...

  7. 学习JavaScript第一周

    三种输出方式,console.log.element.write.alert(): 简单数据类型:数值型.字符串型.布尔类型.undefined.null 复杂数据类型:对象 数据类型的转换:字符串转 ...

  8. 1、HTTP的基本概念与交互模型

    1.上网的整个过程 假设我们点击了某网页上的一个链接,指向清华大学院系设置,其URL是:http://www.tsinghua.edu.cn/chn/yxsz/index.html.我们来分析一下整个 ...

  9. 了解JAVA基本知识以及一下常用的dos命令

    9月5日学习 常用的Dos命令 #盘符切换盘符名称: =>回车​#查看当前目录下的所有文件dir​#切换目录 cd change directorycd .. =>返回上一级目录​#清理屏 ...

  10. login_while

    # -*- coding: utf-8 -*- # @Time : 2020/7/25 22:45 # @Author : Breeze # @FileName: login_while.py use ...