美文网首页数据库
MySQL常见优化

MySQL常见优化

作者: devLiao | 来源:发表于2019-11-27 15:09 被阅读0次

    1,MySQL版本:

    • MySQL Community Server 社区版本,开源免费,但不提供官方技术支持。
    • MySQL Enterprise Edition 企业版本,需付费,可以试用30天。
    • MySQL Cluster 集群版,开源免费。可将几个MySQL Server封装成一个Server。
    • MySQL Cluster CGE 高级集群版,需付费。
    • MySQL Workbench(GUI TOOL)一款专为MySQL设计的ER/数据库建模工具。它是著名的数据库设计工具DBDesigner4的继任者。MySQL Workbench

    又分为两个版本,分别是社区版(MySQL Workbench OSS)、商用版(MySQL Workbench SE)。

    MySQL Community Server 是开源免费的,这也是我们通常用的MySQL的版本。根据不同的操作系统平台细分为多个版本,

    5.X:
    5.0-5.1:早期产品的延续,升级维护
    5.4 - 5.x :MySQL整合了第三方公司的新存储引擎 (5.5 5.7)

    https://blog.csdn.net/vtopqx/article/details/87934889

    2,mysql逻辑分层:连接层,服务层,引擎层,存储层

    https://www.cnblogs.com/sunjingwu/p/9732371.html

    3,存储引擎

    • inndb
      事务有限 行锁
    • myisam
      性能优先 表锁

    查看当前的存储引擎:
    show engines ;
    show variables like '%storage_engine%'

    4,SQL优化

    原因:SQL问题(链接查询),索引失效,服务器参数设置问题(缓冲区,线程数设置不合理)

    1,SQL:解析过程,from,on,join,where, group by, having. select, order by ,limit SQL解析过程
    2,SQL优化,主要就是优化索引
    3,什么是索引:相当于书的目录,索引是帮助MySQL高效获取数据的数据结构 ,索引是数据结构(默认B树)
    4,索引本身很大,需要占用内存和硬盘。不是所有情况都适用,频繁更新的字段不适合

    建立索引会降低增删改的效率

    B树:https://www.bilibili.com/video/av36069871?from=search&seid=1181095641637380064

    5,索引

    • 单值索引:单列,一个表内可以多个单值索引
    • 唯一索引:不能重复
    • 复合索引:多个列构成的索引

    6,SQL性能问题

    1,分析SQL的执行计划:explain 可以模拟SQL优化器执行SQL语句
    • explain + sql语句 查询执行计划
    • select_type :查询类型
    • table :表
    • type :类型
    • possible keys :预测用到的索引
    • key: 实际使用的索引
    • key_len :实际使用索引的长度
    • ref:表之间的引用
    • rows:通过索引查到的数据量
    • extra:额外的信息

    2,explain详解:

    id:

    值相同 从上往下,顺序执行
    多表内连接查询,表执行顺序,因数量的个数改变而改变的原因:笛卡尔积
    数据小的表,优先查询
    id值不同,越大越优先查询

    select_type
    • primary 包含子查询SQL中的主查询(最外层)
    • subquery 包含子查询SQL中的子查询(非最外层)
    • simple:简单查询,不包含子查询,union
    • derived:衍生查询,查询的时候用到了临时表
    • from 子查询 中只有一张表,临时表 select * from(select * from t where t.id in (1,2))tr
    • 在from 子查询中,如果有两张 两张表 union查询,则前面的查询是衍生查询,第二张表则叫union ,
      select * from(select * from t where t.id = 1 union select * from t where t.id = 2)tr
    • union:union查询的除最左表的右表则是union查询
    • union Result:指union 连接出来的临时表
    type

    越左性能越好
    system> const>eq_ref>ref>range>index>all
    system,const 只是理想情况,实际能达到ref>range

    要对type进行优化的前提 是有索引

    • system:只有一条数据的系统表,或衍生表只有一条数据的主查询(select * from (select * from t ) t where id = 1) t表只有一条数据

    • const:仅仅能查到一条数据的SQL,用于primary key 或unique 索引

    • eq_ref:唯一性索引,对于每个索引键的查询,返回匹配唯一行数据,有且只能有一条数据
      常见于唯一索引,和主键索引

    • ref:非唯一性,对于每个索引键的查询,返回匹配的所有行(0,多)
      select * from t where name = 'zs' zs 不唯一

    • range:检索指定范围的行,where 后面是范围查询(between,in ,> < )in可能会失效变成无索引all

    • index:查询全部索引中数据

    • all:查询全部表数据

    type——小结

    system/const:结果只有一条数据
    eq_ref:结果多条,但是每条数据是唯一的
    ref:结果多条,每条数据可以是0或者多条

    possible_keys

    可能用到的索引。预测用到的索引

    key

    实际使用到的索引, 如果是null 则是没有索引

    key_len

    索引长度:用于判断符合索引是否被完全使用
    utf8 一个字符 3个字节 一个字节表示可以为null 两个字节表示可变长度

    ref

    指明当前表所 参照的字段,常量列 const,=‘’等于某个常量
    引用字段 t.id = c.id

    rows

    行数,被索引优化查询的数据个数,通过条件查询出来的数据个数

    extra
    • using filesort:性能消耗大,需要额外一次排序(查找) where a='' order by b 常见于order by
      对于单索引,如果排序和查找是同一个字段则不会出现using filesort,反之
      复合索引,不能跨列,并且最佳最前缀
      单索引:where 什么字段 order by什么字段
      复合索引:where 和 order by按照复合索引的顺序使用,不要跨列或无序使用

    • using temporary 性能损耗大,用到临时表,
      一般出现group by 中,出现在select a2 from t group by a1
      避免:where什么列,就根据哪些列group by

    • using index:性能提升,索引覆盖。
      不读取源文件,只从索引文件中获取数据,不需要回表查询

    不回表查询:如果 select age from t where age = 1 ,假设age是索引列,那么只需要到索引树当中查询数据不需要回表查询其他的数据)
    出现不回表查询则出现using index,

    如果索引覆盖 (using index) 会对possible_keys 和 keys造成影响
    如果没有where,则索引只出现在key中
    如果有where,则出现在key 和 possible_keys中

    • using where:需要回表查询,则会出现using where
      select age,name from where age = 1 ,假设age是索引,则此语句需要回表查询会出现using where

    • impossible where:where 字句永远为false

    3,SQL优化:

    复合索引不能跨列,否则索引失效,可以通过key_len 来观察是否使用到索引
    补充using filesort:复合索引不要跨列使用(where 和 order by 拼起来)没有跨列
    where 和 order by 拼起来是否满足复合索引顺序,满足则不会出现using filesort反之

    1,如果(a,b,c,d)复合索引 和使用的顺序全部一致,则复合索引全部使用,如果部分一致
    则使用部分索引 select a,c where a = and b= and c= and d= 和索引顺序完全一致(不跨列使用)则复合索引全部使用

    2,单表优化:根据SQL实际的解析顺序,调整复合索引的顺序(最佳左前缀)
    索引需要逐步优化。将含in的范围查询放到where 的最后防止失效,失效则会导致后面的索引失效,并且需要回原表查询

    3,多表优化:小表驱动大表,索引建立在经常使用的字段上,左外连接 给外表加索引。

    4,避免索引失效的原则

    (SQL优化是一种概率事件,并不一定达到预想情况)失效的情况大部分适用

    索引优化 是一个大部分情况适用的结论,但由于SQL优化器等原因,结论不是百分百正确
    一般情况,范围查询(>< in),之后的索引失效

    尽量使用索引覆盖,索引不会失效(using index)

    • in 会使索引失效,

    • 复合索引不要跨列(where+order by拼接起来 ),或者无序使用(最佳最前缀)

    • 复合索引尽量使用全索引匹配

    • 不要在索引上进行任何操作,比如计算,函数。否则索引失效

    • 复合索引只要左边有一个失效则右边的索引全部失效

    • 复合索引不能使用 不等于,is null,is not null。否则自身已经右侧索引全部失效

    • like 尽量以常量开头,不要以%开头,否则索引失效

    • 尽量不要包含类型转换(显示,隐式)varchar 字段 = 123 。存在隐式转换

    • 尽量不要使用or ,否则索引失效

    5,SQL优化方法。

    1,exist 和 in 如果主查询的数据集大用 in,如果子查询数据集大,则使用exist
    2,order by,经常看到using filesort 有两种算法,双路排序和单路排序,根据IO的次数

    • 双路排序:双路:扫描两次磁盘。第一次扫描排序字段,排序在buffer 缓冲区进行排序,第二次扫描其他字段
    • 单路排序:只读取一次(全部字段),在buffer中进行排序,但此种单路排序会有一定的隐患,不一定真的是“单路”1次IO,有可能多次IO

    如果数据量特别大,则无法将所有字段的数据读取完毕,进行分片读取,多次读取。单路排序比双路排序占用更多的buffer缓冲区

    可以考虑buffer的容量大小:set max_length_for_sort_data = 1024(字节)

    如果set max_length_for_sort_data值太低,则MySQL会自动从 单路排序切换到双路排序。(太低:需要排序列的总大小超过了max_length_for_sort_data定义的字节数)

    提高order by查询的策略:选择使用单路,双路;调整buffer的容量大小,避免select * ,保证全部的排序字段 排序的一致性(都是升序 或 降序)

    6,SQL排序-慢查询日志

    MYSQL提供的日志记录,用于记录MySQL响应时间超过阈值的SQL语句(long_query_time,默认十秒)
    慢查询日志默认是关闭的,建议,开发调优时打开,而在最终部署时关闭。
    检查是否开启慢查询日志:show variables like '%slow_query_log%',

    开启慢查询日志

    1,临时开启:set global slow_query_log = 1 内存中开启
    2,永久开启:/etc/my.cnf 中追加配置 [mysqld] slow_query_log=1 slow_query_log_file=日志路径

    慢查询阈值:show variables like '%long_query_time%'

    1,临时设置:set global long_query_time,设置完毕重新登录
    2,永久设置:/etc/my.cnf 中追加配置[mysqld] long_query_time=3

    查询超过阈值的SQL条数:show global status like '%slow_queries%'
    通过日志查看具体的慢SQL,通过mysqldumpslow工具

    7,分析海量数据

    • show variables like '%profiling%'
      set profiling = no 开启
      show profiles; 会记录所有profiling 打开后所有执行的语句所花费的时间。只能看到总共消费时间。
    • 精确分析:sql 诊断
      show profile all for query 查询到的SQLid
    • 全局查询日志:记录开始之后的 全部SQL语句。(调优过程中打开)
      show variables like '%general_log%' set global general_log = 1,set global log_output='table'
      开启全局日志 开启之后记录所有SQL,会被记录到MySQL general_log 表中

    相关文章

      网友评论

        本文标题:MySQL常见优化

        本文链接:https://www.haomeiwen.com/subject/zcydwctx.html