SQL分析优化
2022-08-30 14:54:27 46 举报
AI智能生成
SQL分析优化是通过对数据库查询语句进行分析和修改,以提高其执行效率和性能的过程。这包括了对查询语句的结构、索引的使用、数据的存储等方面进行优化。首先,我们需要对查询语句进行解析,找出可能存在的性能瓶颈。然后,我们可以通过添加、删除或者修改索引,来改善查询语句的执行效率。此外,我们还可以通过调整数据的存储方式,如使用分区表或者汇总表,来减少查询的数据量。最后,我们需要对优化后的查询语句进行测试,以确保其性能的提升。总的来说,SQL分析优化是一个系统的过程,需要对数据库的结构和查询语句有深入的理解。
作者其他创作
大纲/内容
慢sql优化
相关配置及命令
# 查看是否开启慢日志记录<br>show variables like 'slow_query%';<br><br>#设置开启慢日志<br>set GLOBAL slow_query_log="ON";<br><br>#设置慢日志记录时间阈值<br>show variables like '%long_query%';<br><br>#查看有多少慢日志<br>show global status like 'slow_queries';<br><br>
mysqldumpslow工具
MySQL提供的mysqldumpslow 的工具,在MySQL的bin目录下
mysqldumpslow --help 查看分析工具支持的各种命令,如查询用时最多的20条慢SQL:<br>mysqldumpslow -s t -t 20 -g 'select' /var/lib/mysql/bab8d9419ec6-slow.log > /data/slow.log<br>
mysqldumpslow查询结果参数: <br>Count :代表这个SQL执行了多少次<br>Time :代表执行的时间,括号里面是累计时间<br>Lock :表示锁定的时间,括号是累计<br>Rows :表示返回的记录数,括号是累计<br>
SQL优化建议
1. 使用预编译提交SQL执行速度<br><br>2. 当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个列名上。这样就可以减少解析的时间并减少哪些有列名歧义引起的语法错误<br><br>3. 多条SQL语句压缩到一句SQL中<br><br>4. 当SQL语句需要union两个查询结果集合时,如果可以判断检索结果中不会有重复的记录时候,应该用union all<br><br>5. 避免使用HAVING字句,因为HAVING只会在检索出所有记录之后才对结果集进行过滤,而where则是在聚合前刷选记录,如果能通过where字句限制记录的数目,那就能减少这方面的开销<br><br>6. 考虑使用“临时表”暂存中间结果,可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能<br>
explain执行计划<br>
执行计划概念
数据库内部对SQL语句分析后决定的执行路径和执行步骤,通俗的说是数据库服务器在执行sql语句的时候,会准备几套方案,最后选择消耗资源最小的方案
Explain各个字段含义
id:<br>id表示执行顺序,id值越大,越先执行;<br>子查询,id的序号会递增;<br>id值相同的情况,可以理解为一组,执行顺序是从上向下。<br>
select_type:<br>SIMPLE:简单的select语句,不包含子查询或者union<br>PRIMARY:查询中包含复杂查询(比如子查询),最外层查询被标记为PRIMARY<br>SUBQUERY:当select或where包含了子查询,该子查询被标记为SUBQUERY<br>DERIVED:表示包含在from子句中的子查询的select<br>UNION:union中第二个或后面的select语句<br>UNION RESULT:代表从union的临时表中读取数据<br>
table:<br>表名,也有可能是别名或者临时表
partitions:<br>当查询的是分区表时,partitions显示分区表命中的分区情况
type:<br>它在 SQL优化中是一个非常重要的指标,以下性能从好到坏依次是:system > const > eq_ref > ref > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL<br><br>system:当表仅有一行记录时(系统表),数据量很少,往往不需要进行磁盘IO,速度非常快<br>const:当命中的是主键或者唯一索引且为常量<br>eq_ref:查询命中的是主键或者唯一索引<br>ref:非唯一性索引,会找到超过一条符合条件的行<br>ref_or_null:与ref类似,只是会额外搜索包含null值的行<br>index_merge:同时使用了两个或两个以上的索引<br>unique_subquery:子查询返回不重复的集合<br>index_subquery:区别于unique_subquery,用于非唯一索引,可以返回重复值<br>range:对有索引的字段,给定范围检索,bettween...and、<、>、<=、in 等<br>index:遍历索引树读取,而all是从硬盘读取<br>ALL:将遍历全表以找到匹配的行,性能最差<br>
possible_keys:<br>mysql可能通过某个索引检索到数据,但不一定最终查询会用到<br>
key:<br>key是查询中实际使用到的索引,若没有使用索引,显示为NULL<br>
key_len:<br>表示查询用到的索引长度(字节数),原则上长度越短越好<br><br>单列索引,那么需要将整个索引长度算进去;<br>多列索引,不是所有列都能用到,需要计算查询中实际用到的列。<br>注:key_len只计算where条件中用到的索引长度,而排序和分组即便是用到了索引,也不会计算到key_len中。<br>
ref:<br>显示该表的索引字段关联了哪张表的哪个字段<br>
rows:<br>根据表统计信息及选用情况,大致估算出找到所需的记录或所需读取的行数,数值越小越好<br>
filtered:<br>filtered 这个是一个百分比的值,表里符合条件的记录数的百分比。这个字段表示存储引擎返回的数据在经过过滤后,剩下满足条件的记录数量的比例
Extra:<br>额外的信息会在 Extra 字段显示<br><br>1.Using index<br>查询到的列被索引覆盖,实际上就是覆盖索引的使用<br>2.Using where<br>查询未用到可用的索引,通过where条件过滤数据<br>3.Using where,Using index<br>通过where条件过滤数据,并且查询用到了覆盖索引<br>4.Using index condition<br>查询使用到了索引,但是需要回表查询,5.6及其以上版本才有,之前是Using where<br>5.Using temporary<br>查询后结果需要使用临时表来存储,一般在排序或者分组查询时用到<br>6.Using filesort<br>无法利用索引完成的排序操作,也就是ORDER BY的字段没有索引<br>7.Using join buffer<br>在我们联表查询的时候,如果表的连接条件没有用到索引,需要有一个连接缓冲区来存储中间结果<br>8.Impossible where<br>在我们用不太正确的where语句,导致没有符合条件的行<br>9.No tables used<br>我们的查询语句中没有FROM子句,或者有FROM DUAL子句<br>
作用总结
根据MySQL执行计划的输出,分析索引使用情况、扫描的行数可以预估查询效率;进而可以重构SQL语句、调整索引,提升查询效率。
Show Profile<br>
简介
<span style="font-size: inherit;">1. Show Profile是mysql提供的可以用来分析当前会话中sql语句执行的资源消耗情况的工具,可用于sql调优的测量;<br></span><br><span style="font-size: inherit;">2. 默认情况下处于关闭状态,并保存最近15次的运行结果;<br></span><br><span style="font-size: inherit;">3. 在MySQL数据库中,可以通过配置profiling参数来启用SQL剖析,该参数可以在全局和session级别来设置,对于全局级别则作用于整个MySQL实例,而session级别紧影响当前session;<br></span><br><span style="font-size: inherit;">4. 该参数开启后,后续执行的SQL语句都将记录其资源开销,诸如IO,上下文切换,CPU,Memory等等,根据这些开销进一步分析当前SQL瓶颈从而进行优化与调整;<br></span><br><span style="font-size: inherit;">5. Show profiles是5.0.37之后添加的,要想使用此功能,要确保版本在5.0.37之后;</span><br>
相关命令
#查看 profiles 是否打开<br>show variables like profiles<br><br>#设置开启profiles功能<br>set profiling=1<br><br>#profiles帮助指令<br>help profile<br><br>#查看执行记录列表<br>Show Profile<br><br>#使用show profile对sql语句进行诊断<br>show profile cpu,block io for query Query_ID;<br>
Show Profile命令结果
show profile cpu,block io for query Query_ID命令结果(Query_ID为Show Profile命令结果中属性)
常用查询参数<br>
①ALL:显示所有的开销信息。<br><br>②BLOCK IO:显示块IO开销。<br><br>③CONTEXT SWITCHES:上下文切换开销。<br><br>④CPU:显示CPU开销信息。<br><br>⑤IPC:显示发送和接收开销信息。<br><br>⑥MEMORY:显示内存开销信息。<br><br>⑦PAGE FAULTS:显示页面错误开销信息。<br><br>⑧SOURCE:显示和Source_function,Source_file,Source_line相关的开销信息。<br><br>⑨SWAPS:显示交换次数开销信息。
show profile常见诊断需优化结果
①converting HEAP to MyISAM:查询结果太大,内存不够,数据往磁盘上搬了<br><br>②Creating tmp table:创建临时表。先拷贝数据到临时表,用完后再删除临时表<br><br>③Copying to tmp table on disk:把内存中临时表复制到磁盘上,危险!!!<br><br>④locked
总结
1. show profile默认是关闭的,并且开启后只存活于当前会话,也就说每次使用前都需要开启。<br><br>2. 通过show profiles查看sql语句的耗时时间,然后通过show profile命令对耗时时间长的sql语句进行诊断。<br><br>3. 注意show profile诊断结果中出现相关字段的含义,判断是否需要优化sql语句。<br>
全局日志
注意事项
该功能主要用于测试环境,在生产环境中永远不要开启该功能。
开启设置
命令开启
1、记录到表中<br><br> set global general_log =1 //开启全局日志,开启后会记录所有sql<br><br> set global log_output='table' //记录sql到系统表general_log中<br><br> select * from mysql.general_log<br><br>2、记录到本地日志文件中<br><br> set global general_log =1<br> set global general_log_file="C:\\Users\\pu\\Desktop\\general.log"<br> set global log_output='file'
配置文件开启
#开启全局查询日志,只能在测试环境下使用,禁止在生产环境下使用<br>general_log=1<br>general_log_file=C:\\Program Files\\MySQL\MySQL Server 5.7\\log\\mysqlLog.log<br><br># 日志输出格式<br>log_output=FILE<br>
查看命令
1. 查看是否开启全局日志<br>show variables like 'general_log';<br><br>2. 查看全局查询日志的配置<br>show variables like "log_output%";<br><br>3.查看全局查询日志的文件<br>show variables like "general_log_file%";<br>
总结<br>
1. 开启全局查询日志之后,你所编写的每一条sql语句都会被记录,仅用作测试时回溯执行SQL的过程记录,配合profile使用<br><br>2. 比如在需要做系统问题分析时,观察和复现线上问题,可以在测试环境下模拟复现情况,使用全局日志可以用general_log这个表来收集什么时间段发生了什么样的SQL,帮助我们定位收集
0 条评论
下一页
为你推荐
查看更多