MySql查询的常用优化策略

150 阅读4分钟

f5445e46a336c9969d5ede7d3f2be60c_800_340.jpg

MySql的索引优化策略掌握之后,绝对会让你在写sql的时候不经意间的就会提升查询性能,潜在内功的修炼,提升程序员的能力

order by关键字优化

  • order by 子句 尽量使用index方式排序,避免使用filesort方式排序
    • mysql支持两种方式的排序,filesort和index,index效率高
    • 它指mysql扫描索引本身完成排序。filesort方式效率较低
    • 使用order by满足两种 排序情况会使用index方式排序
      • order by 子句使用索引最左前列
      • 使用where子句与order by子句条件列 组合满足索引最左前列
  • 尽可能在索引列上完成排序操作,遵照索引建的最佳左前缀
  • 如果不在索引列上,filesort有两种算法:mysql就要启动双路排序单 路排序
    • 双路排序:mysql4.1之前使用双路排序,字面意思就是两次扫描磁盘,最终得到数据,读取行指针和order by列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出从磁盘取排序字段,在buffer进行排序,再从磁盘取其他字段
    • 单路排序:从磁盘读取查询需要的所有列,按照order by列在buffer对他们进行排序,然后扫描排序后的列表进行输出,他的效率更快一些,避免了第二次读取数据。并且把随机io变成了顺序io,但是他会使用更多的空间,因为他把每一行都保存在内存中了

group by 关键字优化

  • 基本和 order by相同
  • group by实质是先排序后分组,遵照索引建的最佳左前缀
  • 当无法使用索引列,增大max_length_for_sort_data参数的设置+sort_buffer_size参数的设置
  • where高于having,能写在where限定的条件就不要去having中限定了

慢查询日志

  • mysql的慢查询日志是mysql提供的一种日志记录,它用来记录在mysql中响应时间超过阙值的语句
  • 具体指运行时间超过long_query_time值的sql,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10秒以上的sql
  • 由它来查看哪些sql超出了我们的最大忍耐时间值,比如一条sql执行超过5秒钟,我们就算慢sql,希望能收集超过5秒的sql,结合上一篇文章中的explain进行全面分析
  • 查看是否开启 show variables like '%slow_query_log%'
  • 开启: set global slow_query_log = 1;
  • 查看当前多少秒算慢 show variables like 'long_query_time' 单位秒
  • 设置慢的阈值时间 set global long_query_time = 3;
  • 查看当前有几条慢sql show global status like '%Slow_queries%'

日志分析工具:mysqldumpslow

  • 一些命令参数含义:
  • s:表明按照何种方式进行排序
  • c:访问次数
  • l:锁定时间
  • r:返回记录
  • t:查询时间
  • al:平均锁定时间
  • ar:平均返回记录数
  • at:平均查询时间
  • t:返回前面多少条的数据
  • g:后面搭配一个正则表达式,大小写不敏感的
--得到返回记录集最多的10个SQL
mysqldumpslow -s r -t 10 /ar/lib/mysql/xslow.log
--得到访问次数最多的10个SQL
mysqldumpslow -s c -t 10 /ar/lib/mysql/xslow.log
--得到按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g "left jin" /var/lib/mysql/xslow.log
--另外建议在使用这些命令时结合|和more 使用,否则有可能出现爆屏情况
mysqldumpslow -s r -t 10 var/lib/mysql/xslow.log | more

show profiles

  • 是mysql提供可以用来分析当前会话中语句执行的资源消耗情况
  • 可以用于sql的调优的测量。
  • 默认情况下,参数处于关闭状态,并保存最近15次的运行结果
  • 分析步骤
    • 查看当前版本是否支持
    • show variables like 'profiling'
    • 开启功能
    • set profiling = 1;
    • 运行sql
    • 查看结果
    • show profiles,出现15条sql记录
    • 诊断sql
    • show profile cpu,block io for query sql的数字号码

image.png

  • 其中还可以查询:
    • all : 显示所有开销信息
    • block io : 显示块io相关开销
    • context switches : 上下文切换相关开销
    • cpu : 显示cpu相关开销信息
    • ipc: 显示发送和接收相关开销信息
    • memory : 显示内存相关开销信息
    • page faults: 显示页面错误相关开销信息
    • source : 显示和source_function,source_file,source_line相关的开销信息
    • swaps : 显示交换次数相关开销的信息
  • 日常开发需要注意的结论
    • status中如果出现下列问题语句,说明sql糟糕
    • converting HEAP to MyISAM :查询结果太大,内存不够用了 往磁盘上搬了
    • creating tmp table 创建临时表
    • Copying to tmp table on disk : 把内存中临时表复制到磁盘,危险!
    • locked 有锁了!

全局查询日志

  • 注意不要在生产环境中开启这个功能
  • 开启:
    • set global general_log = 1;
    • set global log_output = 'TABLE'
  • 此后,所编写的sql语句,将会记录到mysql库里的general_log表,
  • select * from mysql.general_log;

通过上面的操作定位慢sql,使用explain 优化索引的使用。最终达到提升查询效率的结果 i chose you