• MySql进阶 锁 优化 | DAY 15


    计算机协调多个进程或线程并发访问某一种资源的机制

    粒度

    • 全局锁 锁住数据库中所有表
    • 表级锁 锁住整张表
    • 行级锁 锁住对应行数

    全局锁

    锁后 只能进行读取 全库的数据备份 从而获取一致性视图

    全局锁 flush tables with read lock;

    备份 mysqldump -u root -p 12345 database_name > xxx.sql;(在windows命令行执行)

    解锁 unlock tables ;

    在innodb引擎中 备份添加参数 --sing-transaction完成不加锁的一致性备份

    表级锁

    每次操作锁住整张表

    • 表锁
    • 元数据锁
    • 意向锁

    表锁

    • 表共享读锁 所用客户端只能读
    • 表独占写锁 其他客户端读写都被阻塞

    加锁 lock tables table_name read/write

    释放锁 unlock tables

    元数据锁

    系统自动控制加锁 维护表元数据的数据一致性 在表上有活动事务的时候 不可以对元数据进行写入操作

    当对表进行增删改查的时候 自动加锁

    意向锁

    解决在执行dml语句中 加的行锁与表锁的冲突 在innodb引擎加入了意向锁 是的表锁不用检查每行数据是否加锁 使用意向锁来减少表锁的检查

    • 意向共享锁(IS) select…lock in share mode(添加行锁共享锁)
    • 意向排他锁 (IX)insert update delete select…for update

    兼容问题

    **意向共享锁:**与表锁共享锁(read)兼容 与表锁排他锁(write)互斥

    **意向排他锁:**与表锁共享锁(read)以及排他锁(write)都互斥 意向锁之间不会互斥

    行级锁

    锁住对应数据行的数据

    行锁是通过对索引上的索引行加锁来实现的而不是对记录加的锁

    • 行锁 锁定单行数据 防止其他事务对此进行update和delete
    • 间隙锁 锁定索引记录的间隙(不含该记录)确保索引记录间隙不变 防止其他事务在这个间隙进行insert 产生幻读 在RR隔离级别下都支持
    • 临建锁 行锁和间隙锁组合 同时锁住数据并锁住数据前面的间隙

    行锁

    • 共享锁(S)允许一个事务读取一行 阻止其他事务获得相同数据集的排他锁
    • 排他锁(X)允许获取排他锁的事务更新数据 阻止其他事务获取相同数据集的共享锁和排他锁
    sql行锁类型说明
    insert排他锁自动
    update排他锁自动
    delete排他锁自动
    select不加锁
    select…lock in share mode共享锁手动
    select…for update排他锁手动

    间隙锁

    默认情况下 innodb在repeatable read事务隔离级别运行 innodb使用next-key进行搜索和索引扫描 以防止幻读

    1. 索引上的等值查询(唯一索引)给不存在的记录加锁时 优化为间隙锁
    2. 索引上的等值查询(普通索引) 向右遍历时最后一个值不满足查询需求时 临建锁退化为间隙锁
    3. 索引上的范围查询(唯一索引)会访问到不满足条件的第一个值为止

    间隙锁唯一目的是防止其他事务插入间隙 间隙锁可以共存 一个事务采用的间隙锁不会组织两一个事务在同一个间隙上采用间隙锁

    MySQL管理

    系统数据库

    mysql

    存储正常运行的各种信息

    information_schema

    元数据体系 数据库 表 字段类型及访问权限

    performance_schema

    为服务器运行时提供了一个底层监控的功能 主要用于收集服务器性能参数

    sys

    包含了一系列方便dba和开发人员利用performance_schema 性能数据库进行性能调优和诊断

    常用工具

    -u 指定用户名
    -p 指定密码
    -h 指定服务器ip或域名
    -P 指定连接端口号
    -e 执行sql语句并退出(可以在客户端执行sql语句 而不用连接数据库)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    mysqladmin

    执行管理操作的客户端程序 可以用它检查服务器的配置和当前状态 创建并删除数据库等

    不指定主机名和端口号 默认本主机3306

    mysqlbinlog

    服务器生成的二进制文件 需要用到mysqlbinlog管理工具

    mysqlbinlog [options] log-files...

    -d 指定数据库名称
    -o 忽略日志中前n行的命令
    -r 将输出的文本格式日志输出到指定文件
    -s 显示简单个事 省略一些信息
    
    • 1
    • 2
    • 3
    • 4

    SQL优化

    插入数据

    insert优化

    批量插入

    insert into table-name values(1,'tom),(2,'cat)...;

    手动事务提交

    start transction;

    commit

    主键顺序插入

    大批量数据插入

    load指令

    1. 客户端连接服务端时 添加参数 --local-infile
    2. 设置全局参数 set global local_infile=1
    3. 执行load指令 将准备好的数据加载到表结构中去 load data local infile 'filename.log' into table 'table_name' fields terminated by ',' lines terminated by '\n';

    主键优化

    主键设置原则

    • 满足业务需求的情况下 尽量降低主键的长度
    • 插入数据时 尽量选择顺序插入 使用AUTO_INCREMENT自增主键
    • 尽量不要使用UUID做主键或者是其他自然主键 如身份证号
    • 业务操作时避免对主键的修改

    order by优化

    1. using filesort:通过表的索引或全表扫描 读取满足条件的数据行 然后再排序缓冲区sort buffer中完成排序操作 所有不是通过索引直接返回排序结果的牌徐都叫 filesort排序
    2. using idex 通过有序索引顺序扫描直接返回有序数据 这种情况即为using index 不需要额外排序 操作效率高

    需要为排序的字段创建索引

    create index index_name on table_name(字段1,字段2)

    注意创建字段索引的顺序要与排顺时字段顺序相同 (最左前缀法则)

    默认升序排序 asc 降序排序 desc

    创建字段索引时可以指定升序降序

    如果全部字段遵循一致的排列顺序 则不需要额外指定字段排序

    group by优化

    出现 using temporary 临时表 效率极低

    创建联合索引 注意最左前缀法则

    where 先出现group by后出现 依旧可以满足最左前缀法则

    limit优化

    分页查询

    大数据量分页 越往后 耗时越长

    优化 覆盖索引 子查询

    //例子
    select * from table_name limit 9000000,10;
    //优化
    select *from table_name where id in(select id from table_name order by id limit 9000000,10);
    //或者
    select name1.* from table_name1 name1,(select * from table_name order by id limit 9000000,10) name2 where name1.id=name2.id;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    count 优化

    myisam 引擎会把一个表的总行数存在磁盘上 执行count *效率高

    innodb 执行count* 时 需要把数据一行一行地从引擎里读出来 然后累计计数

    优化思路:自己计数 自己维护

    count几种方式

    • count 主键

      • innodb会遍历整张表 每一行的主键提取出来 返回给服务层 服务层进行累加
    • count 字段

      • 没有not null 约束 遍历整张表的每一行的字段返回给服务层 判断是否为null
      • 有约束 每一行提取出来返回给服务层 直接按行累加
    • count *

      • 不取值直接累加
    • count 1

      • 遍历整张表 不取值 放数字进去后直接按行进行累加

    count *效率最高 count 1 count主键 count字段

    update 优化

    update 条件中没有使用索引的话 会锁住整张表

    innodb是针对索引加的锁 不是针对记录加锁 并且索引不能失效 否则行锁升级为表锁

  • 相关阅读:
    VScode连接的服务器上使用jupyter显示请选择内核源
    RAID(独立冗余磁盘阵列)
    liveness-probe探针和readness-probe
    Linux--线程条件控制实现线程的同步
    404 - File or directory not found.
    基于深度学习的人脸表情识别的AR川剧变脸(一)
    玄子Share-服务器硬件及RAID配置实战
    C语言while循环嵌套-动态字母
    Git 开源的版本控制系统-04-branch manage 分支管理
    CentOS docker 和 docker compose 安装
  • 原文地址:https://blog.csdn.net/Ok6668/article/details/136569192