SQL查询优化的步骤
官方文档:Understanding the Query Execution Plan
SQL优化的一般步骤:先查询mysql数据库运行状况,然后定位慢查询,再分析sql的执行过程,最后根据情况采取相应的优化措施。
一、定位慢查询
1.使用show status查询数据库的运行状况
//显示数据库运行状态
SHOW STATUS
//显示数据库运行总时间
SHOW STATUS LIKE 'uptime'
//显示连接的次数
SHOW STATUS LIKE 'connections'
//显示执行CRUD的次数
SHOW STATUS LIKE 'com_select'
SHOW STATUS LIKE 'com_insert'
SHOW STATUS LIKE 'com_update'
SHOW STATUS LIKE 'com_delete'
2.定位慢查询sql
我们可以通过mysql来记录慢查询,一旦有sql执行时间超过了设置的慢查询时间,就会被记录到慢查询日志中。这样我们就可以从慢查询日志中定位慢查询sql,然后进行分析优化。
查看慢查询相关信息
//显示慢查询次数
SHOW STATUS LIKE 'slow_queries'
//显示慢查询时间,默认为10s
SHOW VARIABLES LIKE 'long_query_time'
mysql的慢查询默认是关闭的,可以通过修改配置文件或通过命令来开启。
①修改配置文件方式
Linux下修改my.cnf,Windows下修改my.ini。修改后需要重启mysql才会生效。
#开启慢查询
slow-query-log=1
#慢查询的文件路径
slow_query_log_file="D:/Program Files/MySQL/Log/mysql-slow.log"
#慢查询时间。默认为10秒
long_query_time=10
②命令方式
也可以使用命令来修改。
【session级别】
#开启慢查询
SET slow_query_log='ON'; #设置慢查询日志存放位置
SET slow_query_log_file='/usr/local/mysql/data/slow.log'; #设置慢查询时间
SET long_query_time=3 【global级别】
SET global slow_query_log='ON';
SET global slow_query_log_file='/usr/local/mysql/data/slow.log';
SET global long_query_time=3
3.分析慢查询
在实际生产环境中,可能因为开发写了不正确的SQL语句,索引优化的不好,或其他查询操作而导致数据库整体性能下降。我们只需要分析一下慢查询日志就会知道问题出在哪。
//查看是否启用慢日志记录和状态
show variables like "%slow%"
如果慢查询日志中记录内容较多,则可以使用Mysql自带的慢查询日志分析工具mysqldumpslow工具来对慢查询日志进行分类汇总。该工具位于/mysql/bin目录下。mysqldumpslow将会自动将文本完全一致但变量不同的SQL语句视为同一个语句进行统计,变量值用N来代替。
mysqldumpslow -s r -t 10 /data/dbdata/frem-slow.log
二、使用explain分析sql执行过程
官方文档:Optimizing Queries with EXPLAIN
mysql会将慢查询记录到慢查询日志中,这时我们就可以针对这些慢查询的sql进行分析和优化,需要用到explain命令。
explain [要分析的sql]
分析结果中有如下几列:
+----+-------------+---------+------+---------------+------+---------+------+------+-------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+-------+
下面介绍各列的含义。可以参考官方文档说明:Explain Output Colums
id
表示select查询序列号。id值越大,越优先执行。如果id相同,执行顺序由上至下;
select_type
表示查询操作的类型。主要用于区分普通查询、子查询、联合查询等几种查询情况。有这些取值:simple,primary,subquery,derived,union,union result
①simple:表示简单查询,只有一个select操作,即不使用连接和union。
#只有一个select操作,所以都是简单查询 select id from emp; select id from emp join dept on emp.dept_id=dept.id;
②primary:表示主查询。子查询语句中的最外层select,或union操作的第一个select。
#子查询形式:第一个select操作为primary
select * from app_school where id = (select id from app_school where id=100); #union形式:第一个select操作为primary
select * from app_school where id=100
union
select * from app_school where id=101;
③subquery:表示子查询。子查询语句中的内层select。
#第二个select操作为subquery
select * from app_school where id = (select id from app_school where id=100);
④derived:表示FROM后跟着的select查询,会被标记为derived(导出表/衍生表)。
#第二个select操作为derived
select * from (select id from app_school) t;
⑤union:表示UNION操作后面的select查询。
#第二个select操作为union
select * from app_school where id=100
union
select * from app_school where id=101;
⑥union result:表示获取UNION最后结果的查询。
#第一个select操作为primary
#第二个select操作为union
#获取最终结果的操作为union result
select * from app_school where id=100
union
select * from app_school where id=101;
table
表示查询用到的表。
type
表示找到匹配行用到的访问类型。最为常见的类型有system,const,eq_ref,ref,range,index,All,按照性能从高到低顺序如下:NULL-->system-->const-->eq-ref-->ref-->range-->index-->All 。一般来说,要让查询至少达到range级别,最好能达到ref级别。
①NULL:不用访问表或索引,就可直接得出结果。
②system:该表是最多仅有一行的系统表(这是const类型的一个特例)。系统表中的数据通常已经加载到了内存中,所以不需要磁盘IO。
例子1:查询系统表
例子2:内层嵌套(const)返回了一个临时表,外层嵌套从临时表中查询,其扫描类型也是system,也不需要磁盘IO。
③const:最多只有一个匹配行,所以该行中的其它列的值可以当作常量来处理。例如,根据主键primary key或唯一索引unique index进行查询。简单地说const就是直接按主键或唯一键取值。例如在②中介绍system时的举例中user表的访问类型就是const,其通过主键来取值。
④eq_ref:使用唯一索引,对于每个索引键值,表中只有一条记录匹配。简单说,就是多表连接中使用primary key或unique index作为关联条件。
注意const和eq_ref的区别:简单地说是const
是直接按主键或唯一键读取,eq_ref
用于联表查询的情况,按联表的主键或唯一键联合查询。
⑤ref:使用非唯一索引,或唯一索引的前缀扫描,返回匹配某个单独值的所有行(可能匹配多个行)。
ref还经常出现在join操作中
⑥ref_or_null:与ref类似,区别在于条件中包含对NULL的查询。
⑦index_merge:索引合并优化。
⑧unique_subquery:in的后面是一个查询主键字段的子查询。
⑨index_subquery:与unique subquery类似,区别在于in的后面是查询非唯一索引字段的子查询。
⑩range:只检索指定范围的行,使用一个索引来选择行。常见于<,<=,>,>=,between或者IN操作符。
key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。
.index:索引全扫描。遍历整个索引来查询匹配的行。
12.ALL:全表扫描,性能最差。
possible_keys和key
possible_keys表示查询时可能使用到的索引。key表示实际使用的索引
key_len
表示使用到的索引字段的长度
ref
表示该表的索引字段关联了哪张表的哪个字段
rows
表示扫描行的数量
Extra
表示执行情况的说明和描述。包含不适合在其它列中显示但对执行计划非常重要的额外信息。
三、使用show profile分析sql
有时仅通过explain分析执行计划并不能很快地定位SQL的问题,这时就可以选择profile联合分析。Mysql从5.0.37开始增加了对show profiles和show profile语句的支持。默认profile是关闭的,可以通过set开启session级别的profiling。
//查看是否支持profile
SELECT @@have_profiling
//开启profile(session级别)
set profiling=1;
①执行select语句
②show profiles,查询该sql语句的Query ID.
③通过show profile for query语句能看到执行中线程的每个状态和消耗的时间。
show profile for query [上面的query id]
三、通过trace分析优化器如何选择执行计划
Mysql5.6提供了对sql的跟踪trace,通过trace文件能够进一步了解为什么优化器选择A执行计划而不选择B执行计划,帮助我们更好地理解优化器的行为。
使用方式:
①首先打开trace,设置格式为json,设置trace最大能够使用的内存大小,避免解析过程中因为默认内存过小而不能够完整显示。
//打开trace,设置json格式
SET OPTIMIZER_TRACE="enabled=on",END_MARKERS_IN_JSON=on;
//设置内存
SET OPTIMIZER_TRACE_MAX_MEM_SIZE=1000000;
②接下来执行想做trace的sql语句
select xxx
③检查INFORMATION_SCHEMA.OPTIMIZER_TRACE就知道mysql是如何执行sql的了
SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE
最后会输出一个跟踪文件。
SQL查询优化的步骤的更多相关文章
- MySQL 性能调优——SQL 查询优化
如何设计最优的数据库表结构,如何建立最好的索引,以及如何扩展数据库的查询,这些对于高性能来说都是必不可少的.但是只有这些还不够,要获得良好的数据库性能,我们还要设计合理的数据库查询,如果查询设计的很糟 ...
- SQL查询优化——数据结构设计
本文部分内容会涉及mysql,可能在其它数据库中并不适用. 本章节仅仅针对数据库结构设计做讨论.查询优化的其它内容待续. 数据库设计及使用是WEB开发程序猿必备的一项基础技能,在大数据量和高并发场景, ...
- 引用:初探Sql Server 执行计划及Sql查询优化
原文:引用:初探Sql Server 执行计划及Sql查询优化 初探Sql Server 执行计划及Sql查询优化 收藏 MSSQL优化之————探索MSSQL执行计划 作者:no_mIss 最近总想 ...
- 30条SQL查询优化原则
在我们平常的SQL查询中,其实我们有许多应该注意的原则,以来实现SQL查询的优化,本文将为大家介绍30条查询优化原则. 首先应注意的原则 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 wher ...
- SQL查询优化 LEFT JOIN和INNER JOIN
作者:VerySky 推荐:陈敬(Cathy) SQL查询优化 LEFT JOIN和INNER JOIN 1,连接了八个数据库表,而且全部使用LEFT JOIN,如下所示: Resource_Reso ...
- MySQL SQL查询优化技巧详解
MySQL SQL查询优化技巧详解 本文总结了30个mysql千万级大数据SQL查询优化技巧,特别适合大数据里的MYSQL使用. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ...
- MySQL系列(七)--SQL优化的步骤
前面讲了如何设计数据库表结构.存储引擎.索引优化等内存,这篇文章会讲述如何进行SQL优化,也是面试中关于数据库肯定会被问到的, 这些内容不仅仅是为了面试,更重要的是付诸实践,最终用到工作当中 之前的M ...
- 《打造扛得住的MySQL数据库架构》第7章 SQL查询优化
SQL查询优化 7-1 获取有性能问题SQL的三种方法 如何设计最优的数据库表结构 如何建立最好的索引 如何拓展数据库的查询 查询优化,索引优化,库表结构优化 如何获取有性能问题的SQL 1.通过测试 ...
- 优化 SQL 语句的步骤
优化 SQL 语句的步骤 1.分析MySQL服务器当前的状态信息 SHOW SESSION STATUS; SHOW SESSION STATUS LIKE 'Com_%' //当前会话下所有语句类型 ...
随机推荐
- Linux 下ThinkPHP项目出现_STORAGE_WRITE_ERROR_:./Application/Runtime/Cache/Admin/0dfec61edd66f450033aa87c28a760f4.php
在Linux中部署了ThinkPHP项目,访问时却出现了_STORAGE_WRITE_ERROR_:./Application/Runtime/Cache/Admin/0dfec61edd66f450 ...
- JS 替换所有的空格
在JS中替换掉输入框内的空格,是在处理表单需求的时候极为常用的一项操作,以防止用户的操作习惯引起数据异常,保证传参的安全性. NO.1 name.replace(" "," ...
- iOS UICollectionView数据少导致不能滚动
有时候UICollectionView会遇到不能滑动的情况,但是我们并没有代码明确禁止这个东西的滑动效果,这个是苹果系统的小漏洞. 解决办法: 横向滑动的 collectionView.alwaysB ...
- Nova 的高性能虚拟机支撑
目录 目录 CPU 计算平台体系架构 SMP 架构 NUMA 结构 MMP 结构 Nova 的高性能虚拟机 Nova 虚拟机 CPU/RAM 设计的背景 操作系统许可(Licensing) 性能(Pe ...
- QT Desinger设计窗体应用程序框架
目录 目录 前言 系统软件 QT Designer Using QT Designer Open QTDesigner Tool Widget Box QT Designer的布局 属性栏 示例 i ...
- Python Module_subprocess_调用 Powershell
目录 目录 前言 Powershell call Python Python call Powershell Powershell发送邮件 最后 前言 使用Python内建的subprocess模块, ...
- flutter SnackBar异常Another exception was thrown: Scaffold.of() called with a context that does not contain a Scaffold
代码如下: import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Returning Da ...
- 网页上预览pdf文件的几种方案
网页上查看pdf的方案: 1.使用adobe reader的插件 2.使用在线office控件 3.使用火狐开源项目pdf.js(浏览器需支持html5) 4.将pdf转换为swf文件 5.使用pdf ...
- 使用bat脚本进行开机启动批处理
@echo off//关闭提示信息 start /b "F:\newProject\project\Kinect\Kinect\bin\Debug\" /min Kinect.ex ...
- clearfix:after 的用法
想要清除浮动就要在父元素上 加上 clearfix:after .clearfix:after { <----在类名为“clearfix”的元素内最后面加入内容: content: " ...