首页 > 数据库 >mysql知识点

mysql知识点

时间:2023-11-03 20:12:12浏览次数:42  
标签:知识点 事务 记录 查询 索引 AOF mysql 数据

慢查询

定位

  • 借助第三方检测工具

    • SkyWalking
    • 自研监控系统
  • mysql开启慢查询

    开启慢查询可能会影响mysql服务器的性能,如果硬盘IO已经是瓶颈的话则影响更为明显。

    建议做好以下设置:

    • 控制日志最大大小
    • 定时清理日志
    • 使用其他监控工具
  • 使用性能监控工具

    • arthas

分析

  • 使用 explain or desc
    • 使用key和ken_length来判断是否命中索引
    • 使用type来判断是否走了全索引树扫描和全盘扫描,来判断索引是否需要优化。
    • 使用extra来判断是否需要回表查询来判断
      • 增加索引
      • 调整返回的字段
      • 改变条件字段位置(最左原则)

1698312583803

1698312768210

1698312926638

索引

  • 定义
    以特定的有序数据结构存储指定列数据达到高效检索数据的方式。

数据结构

  • hash

  • 红黑树

    为什么不用它,虽然它动态平衡树,但也是二叉查找树,所以树的深度就会很深,如果数据量较大,并不能很明显的提升检索性能。

  • B树

    多阶多叉路平衡查找树

    • 阶:代表节点上最多存储的数据个数-1。
    • 数据:所有节点都存储数据及指针。
  • B+树

    • 阶数更多。
    • 只有叶子节点存储数据,并且叶子结点是双向链表结构,更加便于范围查找,不用再回到根节点再向下遍历。
    • 非叶子节点存储范围数据以及指针。

分类

  • 聚集索引

    • 索引和数据在一起,叶子节点保存了行数据,每个表必须有,有且仅有一个

    • 要么是主键要么是唯一索引,没有则表会生成rowid组建聚簇索引。

  • 非聚集索引

    • 索引和数据分开,叶子节点存储的是主键,可以有多个
    • 不需要具备唯一性。

    1698316193375

  • 覆盖索引

    返回的数据字段可以在检索条件的索引字段的索引文件中全部找到,则称之为覆盖索引查找,不需要回表。

回表查询

使用带有索引的条件语句检索的结果,并不能满足select需要的字段,需要在聚集索引中二次查找,这种操作称之为回表。

超大分页

使用覆盖索引+子查询优化超大分页查询慢,将部分数据存储在内存中,减少磁盘IO操作,提高查询性能。

以下是一个示例的SQL查询,使用回表策略优化大表查询students表.

# 优化前
SELECT * FROM `students` where name = "zhangsan" LIMIT 10000000,1;

#  优化后
SELECT *
FROM students s1
JOIN (
SELECT id  FROM `students` where name = "zhangsan" LIMIT 10000000,1
) AS s2
ON s1.id = s2.id;

创建原则

  • 数据量够大

    • 数据查询体验很差时就要考虑加了
    • 数据本来预估就很大。
  • 字段选择

    • 条件查询
    • group by
    • order by。
  • 尽量选择区分度高的列建立索引,唯一索引最好。

  • 如果字符串长度较长,建立前缀索引。

    CREATE INDEX idx_email_prefix ON users (email(5));
    
  • 二级索引尽量使用联合索引,减少单列索引

    • 节省储存空间。
    • 更好地利用覆盖索引查询。
  • 如果确定列数据不能存储null,使用not null来约束,尽量也遵守这种约定给到缺省值也好,这样可以使优化器更好地选择更优索引字段。

  • 并不是多多益善,越多增删改代价越高。

索引失效

  • 组合索引
    • 要符合最左前缀原则。
    • 中间有间隔,需要回表。
    • 范围查询右边的列使用不到索引,需要回表。
  • 普通索引
    • 在索引字段使用运算符。
    • 字符串索引字段,字段类型使用错误没有加单引号。(类型转换)
    • 模糊查询,前面有%。

Tips: 最左前缀法则、不能使用函数和运算符、类型使用正确。

优化

表的设计

  • 表的数值类型 tinyint int bigint
  • 合适的字符串类型 char varchar 可变长度效率稍低。
  • 范式设计

语句优化

  • select后面尽量指明字段。
  • 避免使用索引失效的写法。
  • where后面避免对字段使用表达式操作。
    1698320843190
  • 使用union all 替代 union (union会多一次过滤,去除重复数据,性能较差)
  • 尽量是使用inner join,同时尽量把小表放在左边,以小表驱动查询。(inner join会自动化优化小表放在左边作为驱动表,而left join和right join则不会。)

主从复制、读写分离

  • Binlog
    • canal
    • 触发器

1698320674627

分库分表

事务

定义

一组操作的集合,不可分割的工作单元,事务会将这些操作向系统统一提交或者统一撤销,要么同时成功,要么同时失败。

  • 原子性
    不可分割的工作单元,要么一起成功,要么一起失败。
  • 一致性
    事务完成前和完成后,都需要保证系统的一致性,遵循业务系统的约定和规则。
  • 隔离性
    事务之间是隔离独立的,相互之间不受影响。
  • 持久性
    事务完成持久化的数据是持久化落盘的,物理化存储。

并发事务

  • 脏读
    一个事务读到了另外一个事务还没有commit的数据。(读未提交产生)
  • 不可重复读
    同一个事务两次读取的同一条记录数据不一样。(读已提交产生)
  • 幻读
    一个事务在读取时数据记录一直提示不存在,但是当插入这条数据时提示数据已经存在,产生“幻觉”。

以下是解决方案

概念 定义 产生原因 解决方法
脏读 一个事务读取到了另一个事务未提交的数据 事务隔离级别过低,没有锁定正在修改的数据 设置事务隔离级别为读已提交或以上,或者使用排他锁
不可重复读 一个事务在多次读取同一条记录时,得到了不同的结果 事务隔离级别过低,没有锁定已经读取的数据 设置事务隔离级别为可重复读或以上,或者使用共享锁
幻读 一个事务在多次查询同一范围的数据时,得到了不同的结果集 事务隔离级别过低,没有锁定查询范围内的间隙 设置事务隔离级别为串行化,或者使用间隙锁或一致性非锁定读

间隙锁是一种锁定索引范围而非实际数据的锁,它可以锁定一个范围,防止其他事务在这个范围内插入数据,从而保证了范围内的数据的唯一性

事务隔离

  • 未提交读

  • 读已提交

  • 可重复读

  • 串行化

    1698392791129

  • 多版本并发控制(MVCC)

    在MVCC中,每个事务都可以看到一个特定时间点的数据库快照。通过给每个事务分配唯一的事务标识符,并维护每个数据项的多个版本,可以实现并发执行而避免争用和数据不一致性。

redo&&undo

缓冲池

Buffer Pool:当数据库客户端进行增删改查时,为了提升效率都会和Buffer Pool,进行交互,当数据在Buffer Pool中不存在时,缓冲池会将数据行所在的数据页加载到缓冲池供与客户端交互。

数据页:Innodb引擎磁盘管理的最小单元,每一页大小默认为16KB,数据页中存储的是数据行。

脏页:当缓冲池提交到磁盘时,发生错误,在缓冲池存留的数据页就是脏页。

1698394043509

redo log

记录事务提交时数据页物理修改的记录,用于产生脏页时的补救方案。(WAL)

  • 用来二次保证来实现数据事务的持久性
  • 有两份循环写。
  • 当无脏页时,数据会被定时清理。
  • 服务宕机时,可以用来恢复数据。

undo log

回滚日志,用来记录修改前的数据记录,作用:提供回滚、MVCC,保证事务的原子性、一致性

  • delete时,记录一条insert语句。
  • update时,记录一条相反的update语句。
  • insert时产生的日志,commit后就会删除;delete、update则不会删除,MVCC中有用。

排它锁

数据行的排它锁,实现了事务之间的隔离性

MVCC

在聚集索引中有三个隐藏字段

  • 插入事务id或者最后一次修改的事务id(DB_TRX_ID)
  • 回滚指针(DB_ROOL_PTR)
    用来指向回滚段中的 undo 日志记录。
  • DB_ROW_ID
    如果没有配置主键,表自动生成用于充当主键,聚簇索引。
字段 含义 作用
DB_TRX_ID 修改该行记录的事务 id 用于事务的并发控制和回滚
DB_ROLL_PTR 指向回滚段中的 undo 日志记录 用于事务回滚或一致性读
DB_ROW_ID 该行记录的唯一标识符 用于没有主键或非空唯一索引的表的聚集索引

1698397202237

undo log 版本链

多个事务对同一条记录的修改,在undo log文件中生成一条记录的版本链表,表头记录的是最新的旧记录,表尾记录的是最早的旧记录。

readview

  • 当前读
    加行级锁

  • 快照读

    怎么判断快照读读的是那条记录?

    • 当记录中的DB_TRX_ID等于自己事务ID(同一个事务)

    • 小于最小活跃事务ID(其他事务已提交)

    • 同时不再活跃事务列表中,也不可以大于最大事务id。(事务隔离)

    1698399492880

    1698399343943

    • 读已提交:每次读都会生成一个新的快照读。
    • 可重复读:复用第一次读生成的快照。

主从同步

1698402327285

  • 主库
    • binglog:记录DDL以及DML所有操作记录。
  • 从库
    • 通过IOThread同步binglog,写入Relay log
    • 使用SQLThread读取Relaylog,重放Relay log 实现数据同步。

分库分表

  • 垂直分库
    根据业务将表分散到另一个集群的不同的库中。
    1698404025837

  • 垂直分表

    • 根据字段属性将不通字段分配到另一个集群的不通的表中。
      • 冷热分离
        • 根据更新频率区分
        • 是否常用
      • 字段数据大小
        大的描述类字段拆分出来(text、blob)

    1698404413459

  • 水平分库

    将数据拆分到不通集群的多个库中。
    1698405250998

    • 根据id与集群个数取模
    • 预分区划分(range_file)
    • 其他分区算法
  • 水平分表
    将一张大表的数据拆分成多个表(可以在同一个库中)。


知识点

WAL

WAL(Write-Ahead Logging): WAL是一种日志记录技术,它在将数据写入磁盘之前先写入一个称为日志的文件。具体步骤如下:

  1. 在执行事务修改之前,先将修改操作记录到WAL中。
  2. 然后将修改操作应用到内存中的数据结构,使得修改对应的数据项在内存中更新。
  3. 一旦事务所有的修改都已经应用到内存中,将事务标记为已提交。
  4. 最后,将WAL中的日志写入磁盘。

使用WAL的好处是可以提高数据库的性能,因为数据的持久化是通过顺序写入日志文件来完成的,而不是直接写入磁盘的随机写操作。此外,WAL还可以帮助恢复数据库状态,在数据库故障时,可以使用WAL日志文件回放来恢复未提交的事务或丢失的数据。


AOF

AOF(Append-Only File): AOF也是一种日志记录技术,它将每个写操作追加到文件末尾,以日志的形式保存所有修改的指令。具体步骤如下:

  1. 将每个写操作(如SET、DEL等)追加到AOF文件的末尾。
  2. 定期或基于配置选项,对AOF文件进行重写(rewrite),以减小文件大小并移除不必要的指令。
  3. 在数据库重启时,通过重新执行AOF文件中的指令来恢复数据状态。

使用AOF的好处是可以提供更高的持久性和数据安全性,因为AOF记录了每个写操作,所以在数据库故障发生时,可以通过重新执行AOF文件来完整地恢复所有修改。此外,AOF还允许通过将指令追加到AOF文件末尾的方式,实现数据的增量备份。

WAL和AOF都是常见的持久化机制,选择哪种取决于具体的需求和使用场景。一些数据库系统可能支持同时使用WAL和AOF,以提供更强大的数据保护和恢复能力。

标签:知识点,事务,记录,查询,索引,AOF,mysql,数据
From: https://www.cnblogs.com/tyxy/p/17808317.html

相关文章

  • MySQL事务四大特性ACID
    事务:一组操作要么全部成功,要么全部失败,目的是保证数据的一致性。一、事务四大特性ACID(一)原子性(Atomicity)当前事务的操作要么同时成功,要么同时失败。原子性由undolog日志来实现。undolog实现方式当数据库insert一个id=21的数据时,undolog会同时生成一个deleteid=21的sql,当数据......
  • 【Flask框架】全知识点笔记4章60页MD文档,今日主题:flask视图和路由开发
    本文的主要内容:flask视图&路由、虚拟环境安装、路由各种定义、状态保持、cookie、session、模板基本使用、过滤器&自定义过滤器、模板代码复用:宏、继承/包含、模板中特有变量和函数、Flask-WTF表单、CSRF、数据库操作、ORM、Flask-SQLAlchemy、增删改查操作、案例、蓝图、单元测......
  • Mac安装mysql8.0.35
    安装步骤(详细步骤)打开官网https://dev.mysql.com/downloads/mysql/选择自己mac需求的版本以及适合自己mac的版本#查看mac型号架构命令#先commond+空格搜索terminal回车进入终端uname-a先双击打开dmg文件,然后会跳转到pkg里面,双击即可一路下一步即可选......
  • Redhat8.2二进制安装mysql8.0,启动报错
    报错信息:bin/mysql:errorwhileloadingsharedlibraries:libtinfo.so.5:cannotopensharedobjectfile:Nosuchfileordirectory解决办法:ll/usr/lib64/libtinfo.so.6[root@zabbixservermysql]#ln-s/usr/lib64/libtinfo.so.6.2/usr/lib64/libtinfo.so.5[root@zab......
  • Mysql判断表是否存在的思路
    $checkTableExist="SELECTTABLE_NAMEas'table_name'FROMINFORMATION_SCHEMA.TABLESWHERETABLE_SCHEMA='数据库名称'andTABLE_NAMElike'%这里写自己的表名%'";//上面的写法是模糊查询,也可以写成=$tables=Db::query($checkTableExist);$tableDat......
  • MySQL使用函数、存储过程实现:向数据表快速插入大量测试数据
    实现过程创建表CREATETABLE`user`( `id`INT(11)NOTNULLAUTO_INCREMENT, `name`VARCHAR(20)DEFAULTNULL, `age`INT(3)DEFAULTNULL, `pwd`VARCHAR(20)DEFAULTNULL, `address`VARCHAR(30)DEFAULTNULL, PRIMARYKEY(`id`))ENGINE=INNODBAUTO_INCREMENT=......
  • Linux环境Prometheus接入(三、MySQL监控接入mysqld_exporter)
    环境CentOS7.9安装1、命令下载wgethttps://github.com/prometheus/mysqld_exporter/releases/download/v0.15.0/mysqld_exporter-0.15.0.linux-amd64.tar.gztar-zxfmysqld_exporter-0.15.0.linux-amd64.tar.gzmvmysqld_exporter-0.15.0.linux-amd64.tar.gz/home/mysq......
  • ensp实验,大一必学网工基础,数通HCIA内容,详细知识点集合
    1:交换机通信:两个pc端在一个网段内,不用单独配置交换机信息,不用设置网关地址,都能ping通2:路由器通信:Pc的网关地址是路由器的ip地址。路由器配置接口和地址Pc3pingpc4即可3:静态路由:静态路由配置好PC的ip地址、子网掩码、网关和路由器接口的地址信息。在R7路由器输入:[R7]iproute-stat......
  • rpm install MySQL
    yumremovemysql-libs按照依赖关系依次安装rpm包,依赖关系依次为common→libs→client→server。使用命令rpm-ivh{-file-name}进行安装操作。[root@node01mysql]#rpm-ivhmysql-community-common-5.7.36-1.el7.x86_64.rpmwarning:mysql-community-common-5.7.36-1.el......
  • Mysql 逻辑语句
    1、第一种写法selectid,casewhenp_idisnullthen"Root"whenidnotin(selectdistinctp_idfromTreewherep_idisnotnull)then"Leaf"else"Inner"endastype//为该列起别名fromTree 2、第二种写法(case后面有表达式;值1、值2......