• 自学Mysql调优笔记


    Mysql性能调优学习

    预计十天完成14/day

    1. 存储引擎

    存储引擎是基于表的,而不是基于库的

    SHOW ENGINES --展示所有存储引擎
    
    • 1

    1.1 InnoDB

    DML操作遵循ACID模型,支持事务

    行鸡锁,提供并发访问性能。

    支持外键约束,保证数据完整性

    逻辑存储结构

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    一个区64个页,一个page是16k,一个区是1k

    1.2MyISAM

    MyISAM是MySQL早期的默认存储引擎。

    • 不支持事务,不支持外键
    • 支持表锁,不支持行锁
    • 访问速度快

    1.3Memory

    Memory引擎的表数据时存储在内存中的,由于受到硬件问题、或断电问题的影响,只能将这些表作为临时表或缓存使用。

    2). 特点

    • 内存存放
    • hash索引(默认)

    1.4怎么选择

    在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据

    实际情况选择多种存储引擎进行组合。

    • InnoDB: 是Mysql的默认存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操 作,那么InnoDB存储引擎是比较合适的选择。

    • MyISAM : 如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。

      被mongdb取代

    • MEMORY:将所有数据保存在内存中,访问速度快,通常用于临时表及缓存。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,而且无法保障数据的安全性。

      被redis取代

    2.索引

    索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足 特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构 上实现高级查找算法,这种数据结构就是索引。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    假如说MySQL的索引结构采用二叉树的数据结构。

    如果主键是顺序插入的,则会形成一个单向链表,结构如下:

    所以,如果选择二叉树作为索引结构,会存在以下缺点:

    • 顺序插入时,会形成一个链表,查询性能大大降低。
    • 大数据量情况下,层级较深,检索速度慢。

    2.1b+树索引结构

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    B+树只有i叶子节点存储数据,上层只做索引。

    2.2Hash索引

    1. hash索引只能用于对等比较,不支持范围查询(登录的时候)
    2. 无法利用索引完成排序操作
    3. 查询效率高,通常只需要一次检索,效率通常高于B+tree(不发生hash碰撞)

    **在MySQL中,支持hash索引的是Memory存储引擎。 而InnoDB中具有自适应hash功能,hash索引是InnoDB存储引擎根据B+Tree索引在指定条件下自动构建的。 **

    思考题: 为什么InnoDB存储引擎选择使用B+tree索引结构?
    
    A. 相对于二叉树,层级更少,搜索效率高;
    B. 对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储
    的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低;
    C. 相对Hash索引,B+tree支持范围匹配及排序操作;
    D. 双向链表,查询快。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.3索引的分类

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    2.3.1InnoDB的索引

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    where by 。。。 就是根据。。。建立索引

    先查询二级索引在查询聚集索引->回表查询

    思考题:
    以下两条SQL语句,那个执行效率高? 为什么?
    A. select * from user where id = 10 ;
    B. select * from user where name = 'Arm' ;
    备注: id为主键,name字段创建的有索引;
    解答:
    A 语句的执行性能要高于B 语句。
    因为A语句直接走聚集索引,直接返回数据。 而B语句需要先查询name字段的二级索引,然
    后再查询聚集索引,也就是需要进行回表查询。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.SQL优化

    主要优化的是select,其实就是索引

    展示当前数据库是插入为主还是查询为主

    SHOW GLOBAL STATUS LIKE "Com_______"
    
    • 1

    3.1慢查询日志

    • 慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有 SQL语句的日志。

    MySQL的慢查询日志默认没有开启,我们可以查看一下系统变量 slow_query_log。

    修改etc/my.cnf配置信息

    # 开启MySQL慢日志查询开关
    slow_query_log=1
    # 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
    long_query_time=2
    
    • 1
    • 2
    • 3
    • 4

    设置完之后重启mysql

    3.2profile详情

    SELECT @@have_profiling ; # 查看是否开启
    SET profiling = 1 # 设置开启
    show profiles # 查看执行情况
    show profile for query query_id # 查询该sql的耗时情况
    show profile cpu for query query_id # 查看该sql的cpu情况
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.3explain执行计划

    只需要将查询的语句前执行explain关键字

    idselect查询的序列号,表示查询中执行select子句或者是操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行)。
    select_type表示 SELECT 的类型,常见的取值有 SIMPLE
    type表示连接类型,性能由好到差的连接类型为NULL、system、const、 eq_ref、ref、range、 index、all 。、
    possible_key显示可能应用在这张表上的索引,一个或多个。
    key实际使用的索引,如果为NULL,则没有使用索引。
    key_len表示索引中使用的字节数, 该值为索引字段最大可能长度,并非实际使用长 度,在不损失精确性的前提下, 长度越短越好
    rowsMySQL认为必须要执行查询的行数
    filtered表示返回结果的行数占需读取行数的百分比, filtered 的值越大越好。

    3.4索引使用原则

    • 联合索引失效
    • 最左前缀法则

    如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,

    并且不跳过索引中的列。如果跳跃某一列,索引将会部分失效(后面的字段索引失效)。

    • 范围查询

    范围查询右边的列索引会失效 例如:>/<

    规避:在业务允许的情况下,使用大于等于或者小于等于查询

    • 索引运算

    不能在索引上进行运算操作

    • 字符串不加单引号

    索引会失效

    • 模糊查询

    尾部模糊匹配索引不会失效,头部模糊匹配索引会失效。

    • or

    一旦用了or,只有or的两侧都有索引的时候索引才会生效

    • 当全表扫描速度大于索引的时候

    3.5覆盖索引

    尽量使用覆盖索引,减少select *。 那么什么是覆盖索引呢? 覆盖索引是指 查询使用了索引,并 且需要返回的列,在该索引中已经全部能够找到 。

    意思就是返回的列都有索引。

    多用联合索引,联合索引是二级索引,叶子节点下面挂的是id

    3.5sql提示

    explain select * from tb_user use index(idx_user_pro) where profession = '软件工程'; #建议mysql使用哪个索引,mysql内部还是会评估
    explain select * from tb_user ignore index(idx_user_pro) where profession = '软件工程'; #忽略指定的索引
    explain select * from tb_user force index(idx_user_pro) where profession = '软件工程'; # 强制使用索引
    
    • 1
    • 2
    • 3

    3.6前缀索引

    create index idx_xxxx on table_name(column(n)) ; # 我要提取字符串的多少位
    
    • 1

    3.7索引的使用

    多使用联合索引。

    避免回表查询,回一次表,查询的效率要慢10倍

    3.8索引设计原则

    100w数据以上

    1. 针对于数据量较大,且查询比较频繁的表建立索引。
    2. 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索 引。
    3. 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。 (性别,逻辑删除字段,区分度低)
    4. 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。 遵循最左前缀法则
    5. 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,

    避免回表,提高查询效率。

    1. 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增 删改的效率。

    create unique index idx_user_phone_name on tb_user(phone,name);

    1. 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含

    NULL值时,它可以更好地确定哪个索引最有效地用于查询。

    4.sql优化

    4.1插入数据

    • 数据批量插入
    • 数据手动提交

    大批量数据插入 load指定

    4.2主键优化

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    第二页数据被删除一半以上,就会查询其他页然后请求合并。

    主键设计原则
    • 尽量降低主键的长度
    • 因为二级索引下挂载的是用户的主键
    • 尽量使用id自增作为主键
    • 尽量不要使用uuid和身份证号作为主键
    • 主键乱序查询造成页分裂

    4.3order by 优化

    1. Using filesort :通过表的索引或者全表的扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,
    2. Using index:通过有序索引顺序扫描直接返回有序数据,为using index,不需要额外排序,操作效率高

    在创建索引的时候默认是asc的,但是可以指认排序索引的规则

    4.4limit优化

    select * from tb_sku order by id limit 9000000,10
    
    • 1

    通过覆盖索引,加子查询

    select *id from tb_sku order by id limit 9000000,10 #先获取id,再通过id来获取数据
    
    select s.* from tb_sku s, (select id from tb_sku order by id limit 90000000,10) a where s.id = a.id
    
    • 1
    • 2
    • 3

    4.5count优化

    • MyISAM 中把表的总行数放在磁盘上,因为执行count(*)的时候会直接返回这个数,效率高
    • InnoDB,执行count(*)的时候,需要把数据一行一行的遍历出来,然后计算行数(Redis)

    count并不是判断总记录数,而是判断是否为空,为空的话不加

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    4.6update优化

    • 更新字段要根据索引来更新。否则会把行锁升级为表锁,锁住整张表的话会导致每次的更新时间变长

    5锁

    全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。 其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。

    1. 全局锁:锁定数据库中的所有表
    2. 表级锁:幂次操作锁住整张表
    3. 行级锁:每次操作锁住对应的行数据.
  • 相关阅读:
    【新的小主机】向日葵远程控制ubuntu
    函数重入、函数重载、函数重写自己理解
    U++学习笔记 ------ 多播委托
    Shell脚本之awk的用法
    Hadoop 2.x和Hadoop 3.x比较
    delphi组件源码:TMS Diagram Studio 4.27
    正向代理和反向代理有什么区别?什么是正向代理?什么是反向代理?正向代理和反向代理详解。
    【macOS付费软件推荐】第4期:Coherence X
    关于网络安全运营工作与安全建设工作的一些思考
    Dockerfile详解
  • 原文地址:https://blog.csdn.net/giaogege666/article/details/133303707