mysql学习图
慢查询
什么是慢查询:慢查询是指数据库中查询时间超过指定阈值(美团设置为100ms)的SQL,它是数据库的性能杀手,也是业务优化数据库访问的重要抓手。
其实也就是一些比较慢的查询语句,严重的影响性能
用一些工具
越慢的越前面
mysql自带日志
那么知道怎么定位了,那怎么进行优化呢
分析sql语句
explain关键字
最低要求都会限制在range这个地方
explain
回表这个概念
索引
其实上面那一个的时候我对于索引的了解还不够深入
索引:是帮助Mysql高效获取数据的数据结构
这里面要提到一个思想,就是你自己后台进行排序所消耗的性能和时间我认为是不需要去计算的,真正需要很考虑的地方在于用户的读
提升用户读体验当然是做好排序再去进行查找,就像二叉树,logn就可以查找到元素
大大提高了查找效率
当数据量比较大的时候那么红黑树和二叉搜索树的性能就显得不够用了
B树才是性能之选
InnoDB 是事务型数据库的首选引擎,支持事务安全表 (ACID),支持行锁定和外键。MySQL5.5.5 之后,InnoDB 作为默认存储引擎,InnoDB 主要特性有:
- InnoDB 给 MySQL 提供了具有提交、回滚和崩溃恢复能力的事务安全(ACID 兼容)存储引擎。InnoDB 锁定在行级并且也在 SELECT 语句中提供一个类似 Oracle 的非锁定读。这些功能增加了多用户部署和性能。在 SQL 查询中,可以自由地将 InnoDB 类型的表与其他 MySQL 的表的类型混合起来,甚至在同一个查询中也可以混合。
- InnoDB 是为处理巨大数据量的最大性能设计。它的 CPU 的效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。
- InnoDB 存储引擎完全与 MySQL 服务器整合,InnoDB 存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB 将它的表和索引存在一个逻辑表空间中,表空间可以包含数个文件(或原始磁盘分区)。这与 MyISAM 表不同,比如在 MyISAM 表中每个表被存在分离的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被艰制为 2GB 的操作系统上。
- InnoDB 支持外键完整性约束(FOREIGN KEY)。 存储表中的数据时,每张表的存储都按主键顺序存放,如果没有显示在表定义时指定主键,InnoDB 会被每一行生成一个 6B 的 ROWID,并以此作为主健。
- InnoDB 被用在众多需要高性能的大型数据库站点上。 InnoDB 不创建目录,使用 InnoDB 时,MySQL 将在 MYSQL 数据目录下创建一个名为 ibdata1 的 10MB 大小的自动扩展数据文件,以及两个名为ib_logfile() 和 ib_logfile1 的 5MB 大小的日志文件。
聚集索引
聚集索引会有相应的规则和数据在一块
回表查询
回表查询效率就没那么高了,覆盖索引可以一次性就搞定,回表就需要多次了
关于超大分页处理,超大分页需要排序会导致效率巨低
这里就可以很好的看出来前面第一条语句和第二条语句的区别了
select * from tb_sku limit 90000000,10;
这个直接进行排序大部分数据又不要,因为是select *
所以可能又会回表之类的查询,很浪费性能
干脆分开先用id做覆盖查询,再通过t.id=a.id就行了
索引创建原则
联合索引,可以覆盖索引
控制索引数量
什么情况下索引会失效
索引为什么会失效
索引会在以下几种情况下失效:
-
数据更新:当数据库中的数据被更新、删除或插入大量新数据时,原本的索引可能不再有效,尤其是当数据的分布发生显著变化时。
-
索引选择错误:如果查询使用了一个不适合的索引,可能导致全表扫描,索引失效。例如,在某些情况下,如果查询条件中的列不是索引的最左边列(对于复合索引),该索引就不会被使用。
-
查询条件使用了函数或表达式:如果查询条件中的列应用了函数或进行了计算,索引将无法使用。例如,
WHERE SUBSTR(column_name, 1, 3) = 'abc'
这样的条件会导致索引失效。 -
模糊查询:在使用
LIKE
进行模糊查询时,如果通配符出现在字符串的开头(例如LIKE '%value'
),索引将不会生效。 -
小表或低选择性列:当表数据量很小或者查询的列数据重复度较高(即低选择性),数据库优化器可能会选择不使用索引,而是直接进行全表扫描。
-
隐式类型转换:如果查询中索引列的类型与查询条件中的值类型不一致,可能发生隐式类型转换,导致索引失效。
-
统计信息过时:数据库中的统计信息未及时更新,可能导致优化器选择不合适的索引,从而导致索引失效。
了解这些情况有助于在数据库设计和查询优化中有效避免索引失效,从而提高查询性能。
具体的原理可以看
https://www.51cto.com/article/702691.html
sql优化
阿里开发手册可能还有很多企业也有这种类型的手册可以多学学
很多内部规范
union联合查询会把重复数据过滤掉比union all效率低,开发的时候用union all
这里也有主从复制,和redis集群那块一样的一样可以读写分离,主从复制
事务
事务这块我觉得很简单
数据库课内也已经学了,主要是ACID这几个原则
并发事务可能带来哪些后果
默认隔离级别是可重复读
问题还是需要清楚的
我觉得关于幻读还需要一些具体的解释:
幻读的产生场景
幻读通常发生在以下情况下:
-
事务A执行查询:事务A在一个表中执行了查询,获取了一组数据。
-
事务B插入或删除数据:此时,事务B在事务A查询的范围内插入了新记录或删除了记录。
-
事务A再次执行相同的查询:事务A再次执行同样的查询时,发现返回的结果集发生了变化,即出现了“幻影”数据(新增或删除的记录),导致前后两次查询结果不一致。
幻读与其他并发问题的区别
幻读与脏读(Dirty Read)和不可重复读(Non-Repeatable Read)是不同的并发问题:
-
脏读:事务A读取了事务B尚未提交的修改,当事务B回滚时,事务A读取的数据就成了无效的“脏数据”。
-
不可重复读:事务A在一个事务中两次读取同一行数据,期间事务B修改了该行数据,导致事务A前后两次读取的结果不一致。
-
幻读:事务A在一个事务中两次查询同一范围的数据,期间事务B在该范围内插入或删除了数据,导致事务A前后两次查询的结果集大小不同。
redis里面有持久化,mysql里面也有,都是为了保持数据库里的数据持久,一致性
包括采用的一些方案都很相似
逻辑日志?
undo log解释
在MySQL中,**Undo Log(回滚日志)**是一种用于记录数据库事务操作的日志,用以支持事务的回滚和多版本并发控制(MVCC)。Undo Log的主要作用如下:
1. 支持事务回滚
- 作用:当一个事务执行时,MySQL会在执行每一条修改操作之前,将数据被修改前的状态记录到Undo Log中。如果事务由于某种原因需要回滚(例如遇到错误或显式回滚),MySQL可以通过读取Undo Log中的信息,将数据恢复到事务开始前的状态,从而撤销该事务的所有操作。
- 过程:假设一个事务更新了某一行数据,Undo Log会记录这行数据的旧值。如果事务需要回滚,MySQL会用Undo Log中记录的旧值恢复这行数据。
2. 支持多版本并发控制(MVCC)
- 作用:Undo Log还用于支持MVCC,它允许数据库在高并发环境下实现一致性读。通过MVCC,不同的事务可以看到数据在不同时间点的版本,而不必阻塞其他事务的写操作。
- 过程:当一个事务进行查询时,MySQL根据Undo Log为每一行生成一个特定版本的快照,这样,事务可以看到符合其一致性要求的数据版本,即使其他事务在同时对数据进行了修改。
3. Undo Log的存储
- 位置:Undo Log通常存储在数据库的系统表空间或独立的Undo表空间中,它以链表的形式组织,每一条修改操作的Undo Log都链接到前一条相关操作的Undo Log上。
- 清理:当事务提交后,如果没有其他事务需要使用Undo Log中的数据版本,MySQL会在后台清理不再需要的Undo Log,以释放空间。
4. Undo Log类型
- Insert Undo Log:记录插入操作的日志,用于回滚插入操作。
- Update Undo Log:记录更新操作的日志,包含更新前的旧数据,用于回滚更新操作。
- Delete Undo Log:记录删除操作的日志,用于回滚删除操作。
5. Undo Log与Redo Log的区别
- Undo Log:记录的是数据的旧版本,用于回滚事务,确保数据库可以恢复到某个特定状态。
- Redo Log:记录的是数据的新版本,用于在系统崩溃后恢复未完成的事务,确保事务的持久性。
通过理解Undo Log的作用和工作机制,可以更好地理解MySQL事务的实现原理以及如何维护数据的完整性和一致性。
其实嘛我明白了就是去和新操作做一个相反的操作,方便去回滚到旧状态
MVCC
什么是MVCC
MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读
- 当前读:像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。
- 快照读:像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本
MVCC实现具体原理
undo log回滚日志
MVCC还得去多去具体看看
Mysql主从同步
分库分表
垂直不同业务
垂直分表,冷热数据
一些热点可以自己再处理
单表过大,拆分
两种中间件
解决问题
我觉得分库分表这里内容还是比较复杂,大家可以去谷歌看看其它博客