.1. 数据库三大范式
第一范式( 1NF): 字段具有原子性,不可再分
。
**第二范式( 2NF):**是在第一范式( 1NF) 的基础上建立起来的,要求数据库表中的每个实例或行必须可以被惟一地区分
。通常需要为表加上一个列, 以存储各个实例的惟一标识。 这个惟一属性列被称为主关键字或主键。
第三范式( 3NF): 必须先满足第二范式( 2NF)。 简而言之, 第三范式( 3NF) 要求一个数据库表中不包含已在其它表中已包含的非主关键字信息
。所以第三范式具有如下特征:1, 每一列只有一个值。2, 每一行都能区分。3,每一个表都不包含其他表已经包含的非主关键字信息
。
.2. 嵌套事务
嵌套是子事务套在父事务中执行,子事务是父事务的一部分,在进入子事务之前,父事务建立一个回滚点,叫 save point
,然后执行子事务,这个子事务的执行也算是父事务的一部分,然后子事务执行结束,父事务继续执行。重点就在于那个 save point。
-
如果子事务回滚,会发生什么?
- 父事务会回滚到进入子事务前建立的 save point,然后尝试其他的事务或者其他的业务逻辑,父事务之前的操作不会受到影响,更不会自动回滚。
-
如果父事务回滚,会发生什么?
- 父事务回滚,子事务也会跟着回滚!为什么呢,因为父事务结束之前,子事务是不会提交的,我们说子事务是父事务的一部分
-
事务的提交,是什么情况?
- 是父事务先提交,然后子事务提交,还是子事务先提交,父事务再提交?答案是第二种情况,还是那句话,
子事务是父事务的一部分,由父事务统一提交
。
- 是父事务先提交,然后子事务提交,还是子事务先提交,父事务再提交?答案是第二种情况,还是那句话,
.2. 数据库事务
- 事务:主要用于
处理操作量大,复杂度高的数据
。一般来说,事务是必须满足 4 个条件(ACID):- ** 原子性:** 所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- ** 一致性:** 在事务开始之前和事务结束以后,
数据库的完整性没有被破坏
。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。 - ** 隔离性:** 数据库允许
多个并发事务同时对其数据进行读写和修改的能力
,隔离性可以防止多个事务并发执行时由于交叉执行,而导致数据的不一致。事务隔离分为不同级别读未提交 (脏读)
:最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果
。所有的并发事务问题都会发生读提交 (读旧数据,不可重复读问题)
:只有在事务提交后
,其更新结果才会被其他事务看见。可以解决脏读问题。可重复读
(解决了脏读但是有幻影读):在一个事务中
,对于同一份数据的读取结果总是相同的
,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。串行化
:事务串行化执行
,隔离级别最高,牺牲了系统的并发性
。可以解决并发事务的所有问题。
- ** 持久性:** 事务处理结束后,对数据的修改就是
永久的
,即便系统故障也不会丢失。
.2. 如何保证事务ACID特性
- 隔离性:采用锁机制 来实现;表锁和行级锁
- 共享锁:可以并发读取数据,但不能修改数据
- 排他锁:
- 更新锁:资源的更新锁一次只分配给一个事务,如果需要对资源进行修改,更新锁变为排它锁,否则是共享锁
- 原子性,一致性,持久性: 通过日志方式。
.2. Mysql 页级、表级、行级锁
- ** 表级锁:** 开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
- ** 行级锁:** 开销大,加锁慢;
会出现死锁
;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。 - ** 页面锁:** 开销和加锁时间界于表锁和行锁之间;
会出现死锁
;锁定粒度界于表锁和行锁之间,并发度一般
.2. 并发事务问题
- 脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是 “脏数据”,依据 “脏数据” 所做的操作可能是不正确的。
- 丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。例如:事务 1 读取某表中的数据 A=20,事务 2 也读取 A=20,事务 1 修改 A=A-1,事务 2 也修改 A=A-1,最终结果 A=19,事务 1 的修改被丢失。
- 不可重复读(Unrepeatable read): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
- 幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 允许 | 允许 | 允许 |
读已提交 | 不允许 | 允许 | 允许 |
可重复读 | 不允许 | 不允许 | 允许 |
串行化 | 不允许 | 不允许 | 不允许 |
.3. 如何解决并发性问题
- 版本检查:
- 共享锁、乐观锁、悲观锁
.3. 一对多和多对一场景
-
** 一对多:** 当在数据库的设计中,涉及到一个对象可以包含多个另外对象,而单个另外对象只能对应一个对象时就产生了一对多的关系,例学生和班级,这种情况通常将外键设在多的对象表结构中。
-
** 多对多:** 当在数据库的设计中,涉及到一个对象可以包含多个另外对象,而单个另外对象也对应多个对象时就产生了多对多的关系,例书籍和作者,这种情况通常将外键设在多的对象表结构中。
.4. 触发器、函数、视图、存储过程
- 触发器: 使用触发器可以
定制用户对表进行【增、删、改】操作时前后的行为
,触发器无法由用户直接调用,而由于对表的【增 / 删 / 改】操作被动引发的 - 函数: 是 MySQL 数据库提供的
内部函数
(当然也可以自定义函数
)。这些内部函数可以帮助用户更加方便的处理表中的数据,avg, min, count, sum, upper, lower, hour, year - 视图: 视图是
虚拟表或逻辑表
,它被定义为具有连接的 SQL SELECT 查询语句。 - 存储过程: 存储过程是
存储在数据库目录中的一堆的声明性 SQL 语句
,数据库中的一个重要对象,有效提高了程序的性能
.5. 数据库索引
- 唯一索引(
UNIQUE
):索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。 - 主键索引(
PRIMARY
):一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引。 - 普通索引(
INDEX
):最基本的索引,没有任何限制。 - 组合索引:多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合。
.5. 索引缺点
-
【不要】创建索引
-
表经常进行 INSERT/UPDATE/DELETE 操作
-
表很小 (记录超少)
-
列名不经常作为连接条件或出现在 WHERE 子句中
-
-
索引优缺点
- 索引加快数据库的检索速度
- 索引
降低了插入、删除、修改等维护任务的速度
(虽然索引可以提高查询速度,但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引) - 唯一索引可以确保每一行数据的唯一性,通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能
- 索引需
要占物理和数据空间
4. 什么是存储过程?用什么来调用?
存储过程是一个预编译的 SQL 语句
,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次 SQL,使用存储过程比单纯 SQL 语句执行要快。
1)可以用一个命令对象来调用存储过程。
2)可以供外部程序调用,比如:java 程序。
.5. 索引数据结构
- B 树,B + 树,Hash (直接定址法,平方取中法,折叠法,除数取余法,随机数法),位图索引
.6. 主键和外键
- ** 主键:** 是指表中一个列或者列的组合,其值能够
唯一的标识表中的每一个行
。这样的一列或者多列成为表的主键,通过它可以强制表的实体完整性。当创建或者更改表时可以通过定义PRIMARY KEY
约束来创建主键,一个表只能有一个主键约束,而且主键约束中的列不能是空值
,由于主键约束确保唯一数据,所一经常来定义标识列。 - ** 外键:** 外键是建立于
表与表之间的联系
。外键保证了数据的完整性,使用外键,简单直观,可以直接在数据模型中体现,无论是设计、维护等。 - 超键:在关系中能
唯一标识元组的属性集
称为关系模式的超键。一个属性可以为作为一个超键
,多个属性组合在一起也可以作为一个超键
。超键包含候选键和主键。 - 候选键:
是最小超键
,即没有冗余元素的超键。
.6. 为什么用自增列作为主键
- 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
- 如果使用非自增主键(如果身份证号或学号等),由于
每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置
,此时 MySQL 不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过 OPTIMIZE TABLE 来重建表并优化填充页面。
.7. 创建索引但是无法命中索引的 8 种情况
- 查询条件中有 or、not in、not exist 等
- 小表查询
- like 查询是以 % 开头
- 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
- 没有使用索引字段查询
- 对索引列进行运算,需要建立函数索引
- 单独引用联合索引中的非第一位置的索引
- 没有查询条件
.8. char 和 varchar之间区别
- char 的长度是不可变的,而 varchar 的长度是可变的。
- char 的存取速度还是要比 varchar 要快得多,因为其长度固定,方便程序的存储与查找;但是 char 也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率,而 varchar 是以空间效率为首位的。
- char 的存储方式是,对英文字符(ASCII)占用 1 个字节,对一个汉字占用两个字节;而 varchar 的存储方式是,对每个英文字符占用 2 个字节,汉字也占用 2 个字节。
.9. 使用limit offset 为什么越往后越慢
-
原因:MySQL 的
limit m n
工作原理就是先读取前面m+n
条记录,然后抛弃前m
条,读后面n
条想要的,所以m
越大,偏移量越大,性能就越差。 -
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
-
解决方案:
-
limit 限制优化法:把 limit 偏移量限制低于某个数。超过这个数等于没数据
-
存储本页数据两端的主键,按主键查找后向前或向后取多少条
-
SELECT ... FROM single_table ... ORDER BY non_index_column [DESC] LIMIT [M,]N;
-
.10. sql注入
.12. 红黑树和AVL树
- 红黑树不追求 “完全平衡”, 任何不平衡在三次旋转之内解决, 减少频繁的移动,
- AVL 树: 更平衡,时间效能对读取较高,维护较慢,开销大
12. B树和B+树区别
B 树每个节点都存储数据
,所有节点组成这棵树。B + 树只有叶子节点存储数据
(B + 数中有两个头指针:一个指向根节点,另一个指向关键字最小的叶节点),叶子节点包含了这棵树的所有数据,所有的叶子结点使用链表相连
,便于区间查找和遍历
,所有非叶节点起到索
引作用。- B + 树中查找,无论查找是否成功,每次都是一条
从根节点到叶节点的路径
。 - B 树中
叶节点包含的关键字和其他节点包含的关键字是不重复的
,B + 树的索引项只包含对应子树的最大关键字和指向该子树的指针,不含有该关键字对应记录的存储地址。
13. 图片在数据库中怎么存储的
- 将
图片保存的路径存储到数据库
; - 将图片以二进制数据流的形式直接写入数据库字段中。
15. MVCC
**快照读 (snapshot read):**读取的是记录的可见版本
(有可能是历史版本),不用加锁(共享读锁 s 锁也不加,所以不会阻塞其他事务的写)
**当前读 (current read):**读取的是记录的最新版本
,并且,当前读返回的记录,都会加上锁
,保证其他事务不会再并发修改这条记录
todo :https://posts.careerengine.us/p/61762a161590276a0e56a18d
16. MyISAM 和 InnoDB 引擎
- InnoDB 引擎:MySQL 的 5.5 之后的默认引擎,InnoDB 引擎提供了
对数据库事务的支持
,并且还提供了行级锁和外键的约束
,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。 - MyISAM 引擎:不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即
执行写操作的时候需要锁定这个表
,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数
,于是当进行 select count (*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。 - 是否支持行级锁 : MyISAM 只有表级锁 (table-level locking),而 InnoDB 支持行级锁 (row-level locking) 和表级锁,默认为行级锁,适合高并发操作。
- 是否支持外键: MyISAM 不支持,而 InnoDB 支持
- 是否支持事务:MyISAM 不支持,而 InnoDB 支持
- 缓存:MyISAM 只
缓存索引
,InnoDB 缓存索引和真实数据
,所以对内存要求高 - 崩溃恢复:
MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多
,而且恢复的速度也更慢。 - 索引区别
- MyIASM 引擎,B + 树的数据结构中存储的内容实际上是实际数据的地址值。也就是说它的索引和实际数据是分开的,只不过使用索引指向了实际数据。这种索引的模式被称为非聚集索引。
- Innodb 引擎的索引的数据结构也是 B + 树,只不过数据结构中存储的都是实际的数据,这种索引有被称为聚集索引。
16.Innodb特性
- 插入缓冲(insert buffer), 二次写 (double write), 自适应哈希索引 (ahi), 预读 (read ahead)
16. where 与 having 的区别
-
用的地方不一样
where 可以用于 select、update、delete 和 insert into values (select * from table where …) 语句中。
having 只能用于 select 语句中
-
执行的顺序不一样
where 的搜索条件是在执行语句进行分组之前应用
having 的搜索条件是在分组条件后执行的
即如果 where 和 having 一起用时,where 会先执行,having 后执行
.17. 批量往 mysql 导入 1000 万数据有什么方法?
- 减少 IO 次数
SQL 写法优化,一条 SQL 语句插入多条数据
- 合理设置
批量大小
- 尽量顺序插入, 减少索引的维护压力
.18. drop、delete 与 truncate
不再需要一张表
的时候,用 drop- 想
删除部分数据行
时候,用 delete,并且带上 where 子句 保留表而删除所有数据
的时候用 truncate
.20. MySQL 权限相关的表
user 权限表
:记录允许连接到服务器的用户帐号信息
,里面的权限是全局级的。db 权限表
:记录各个帐号
在各个数据库上的操作权限。table_priv 权限表
:记录数据表级的操作权限。columns_priv 权限表
:记录数据列级的操作权限。host 权限表
:配合 db 权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受 GRANT 和 REVOKE 语句的影响。
.21. 聚簇索引与非聚簇索引
- 聚簇索引:是一种数据存储方式,而不是索引类型,将数据存储和索引放到一起,INNODB 表中,非叶子节点按照主键顺序存放,叶子节点存放主键以及对应的记录。
- 非聚簇索引: 叶子存储的是指向数据地址的指针
.22. 数据库读写分离
主服务器
用来处理写操作
以及实时性要求比较高的读操作
,而从服务器
用来处理读操作
。
读写分离常用代理方式
来实现,代理服务器接收应用层传来的读写请求,然后决定转发
到哪个服务器。
MySQL 读写分离能提高性能的原因在于:
- 主从服务器负责各自的读和写,极大程度
缓解了锁的争用
; 从服务器可以配置 MyISAM 引擎,提升查询性能以及节约系统开销;
- 增加冗余,提高可用性。
.23. Mysql 的复制原理
Mysql 支持两种复制:基于行的复制
和基于语句的复制
。
这两种方式都是在主库上记录二进制日志
,然后在从库重放日志的方式
来实现异步的数据复制。这意味着:复制过程存在时延,这段时间内,主从数据可能不一致。
主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。
- binlog 线程 :负责将主服务器上的数据更改写入二进制文件(binlog)中。
- I/O 线程 :负责从主服务器上读取二进制日志文件,并写入从服务器的中继日志中。
- SQL 线程 :负责读取中继日志并重放其中的 SQL 语句。
.24. 主从复制方式
- ** 同步复制:** 所谓的同步复制,意思是 master 的变化,必须等待 slave-1,slave-2,…,slave-n 完成后才能返回。 这样,显然不可取,也不是 MySQL 复制的默认设置。比如,在 WEB 前端页面上,用户增加了条记录,需要等待很长时间。
- ** 异步复制:** 如同 AJAX 请求一样。master 只需要完成自己的数据库操作即可。至于 slaves 是否收到二进制日志,是否完成操作,不用关心,MySQL 的默认设置。
- ** 半同步复制:**master 只保证 slaves 中的一个操作成功,就返回,其他 slave 不管。 这个功能,是由 google 为 MySQL 引入的。
.25. 数据库binlog, redolog, undolog
-
binlog: 记录数据库
执行的写入性操作
(不包括查询) 信息,以二进制的形式保存在磁盘中。binlog
是mysql
的逻辑日志,并且由Server
层进行记录,使用任何存储引擎的mysql
数据库都会记录binlog
日志。binlog
是通过追加的方式
进行写入的,可以通过max_binlog_size
参数设置每个binlog
文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志。- 主从复制 :在
Master
端开启binlog
,然后将binlog
发送到各个Slave
端,Slave
端重放binlog
从而达到主从数据一致。 - 数据恢复 :通过使用
mysqlbinlog
工具来恢复数据。 - 刷盘时机:
- 0:不去强制要求,由系统自行判断何时写入磁盘;
- 1:每次
commit
的时候都要将binlog
写入磁盘; - N:每 N 个事务,才会将
binlog
写入磁盘。
-
redo log: 包括两部分:一个是内存中的日志缓冲 (
redo log buffer
),另一个是磁盘上的日志文件 (redo logfile
)。mysql
每执行一条DML
语句,先将记录写入redo log buffer
,后续某个时间点再一次性将多个操作记录写到redo log file
。这种 先写日志,再写磁盘 的技术就是MySQL
里经常说到的WAL(Write-Ahead Logging)
技术。 -
undolog: undo 日志用于
记录事务开始前的状态,用于事务失败时的回滚操作
;redo 日志记录事务执行后的状态,用来恢复未写入 data file 的已成功事务更新的数据。例如某一事务的事务序号为 T1,其对数据 X 进行修改,设 X 的原值是 0,修改后的值为 1,那么 Undo 日志为 <T1, X, 0>,Redo 日志为 < T1, X, 1>。
26. 事务是如何通过日志来实现的
事务日志是通过 redo 和 innodb 的存储引擎日志缓冲(Innodb log buffer)来实现的,当开始一个事务的时候,会记录该事务的 lsn (log sequence number) 号;当事务执行时,会往 InnoDB 存储引擎的日志的日志缓存里面插入事务日志;当事务提交时,必须将存储引擎的日志缓冲写入磁盘(通过 innodb_flush_log_at_trx_commit 来控制),也就是写数据前,需要先写日志。这种方式称为 “预写日志方式”
27. NULL 意思
NULL 这个值表示 UNKNOWN (未知)
: 它不表示 “”(空字符串)。对 NULL 这个值的任何比较都会生产一个 NULL 值。您不能把任何值与一个 NULL 值进行比较,并在逻辑上希望获得一个答案。使用 IS NULL
来进行 NULL 判断
28. 完整性约束
- 实体完整性:规定表的每一行在表中是惟一的实体。
- 域完整性:是指表中的列必须满足某种特定的数据类型约束,其中约束又包括取值范围、精度等规定。
- 参照完整性:是指两个表的主关键字和外关键字的数据应一致,保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据库中扩散。
- 用户定义的完整性:不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。用户定义的完整性即是针对某个特定关系数据库的约束条件,它反映某一具体应用必须满足的语义要求。
29. sql 语句包括哪几部分
SQL 语言包括数据定义 (DDL)、数据操纵 (DML), 数据控制 (DCL) 和数据查询(DQL)四个部分。
- 数据定义:Create Table,Alter Table,Drop Table, Craete/Drop Index 等
- 数据操纵:Select ,insert,update,delete,
- 数据控制:grant,revoke
- 数据查询:select
30.MySQL 数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
- 设计良好的数据库结构,允许部分数据冗余,尽量避免 join 查询,提高效率。
- 选择合适的表字段数据类型和存储引擎,适当的添加索引。
- mysql 库主从读写分离。
- 找规律分表,减少单表中的数据量提高查询速度。
- 添加缓存机制,比如 memcached,redis 等。
- 不经常改动的页面,生成静态页面。
31. 如果一个表有一列定义为 TIMESTAMP,将发生什么?
每当行被更改时,时间戳字段将获取当前时间戳。
32. 列设置为 AUTO INCREMENT 时,如果在表中达到最大值,会发生什么情况?
它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。
33. LIKE 声明中的%和_是什么意思
%对应于 0 个或更多字符,_只是 LIKE 语句中的一个字符。
- 使用
LIKE %abc%
不会走索引,而使用LIKE abc%
会走索引
34. 为什么使用 select * from table 会使得查询效率低?
select * 语句取出表中所有的字段,会解析更多的对象,字段,权限,属性等
,无论该字段的数据对调用的程序是否有用,这会造成服务器资源的浪费,导致优化和效率问题,对服务器的性能产生一定的影响
35.EXPLAIN 的字段有哪些,具有什么含义?
执行计划是 SQL 调优的一个重要依据,可以通过 EXPLAIN 命令查看 SQL 语句的执行计划
,如果作用在表上,那么该命令相当于 DESC。EXPLAIN 的指标及含义如下:
指标名 | 含义 |
---|---|
id | 表示 SELECT 子句或操作表的顺序,执行顺序从大到小执行,当 id 一样时,执行顺序从上往下。 |
select_type | 表示查询中每个 SELECT 子句的类型,例如 SIMPLE 表示不包含子查询、表连接或其他复杂语法的简单查询,PRIMARY 表示复杂查询的最外层查询,SUBQUERY 表示在 SELECT 或 WHERE 列表中包含了子查询。 |
type | 表示访问类型,性能由差到好为:ALL 全表扫描、index 索引全扫描、range 索引范围扫描、ref 返回匹配某个单独值得所有行,常见于使用非唯一索引或唯一索引的非唯一前缀进行的查找,也经常出现在 join 操作中、eq_ref 唯一性索引扫描,对于每个索引键只有一条记录与之匹配、const 当 MySQL 对查询某部分进行优化,并转为一个常量时,使用这些访问类型,例如将主键或唯一索引置于 WHERE 列表就能将该查询转为一个 const、system 表中只有一行数据或空表,只能用于 MyISAM 和 Memory 表、NULL 执行时不用访问表或索引就能得到结果。SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts 最好。 |
possible_keys | 表示查询时可能用到的索引,但不一定使用。列出大量可能索引时意味着备选索引数量太多了。 |
key | 显示 MySQL 在查询时实际使用的索引,如果没有使用则显示为 NULL。 |
key_len | 表示使用到索引字段的长度,可通过该列计算查询中使用的索引的长度,对于确认索引有效性以及多列索引中用到的列数目很重要。 |
ref | 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。 |
rows | 表示 MySQL 根据表统计信息及索引选用情况,估算找到所需记录所需要读取的行数。 |
Extra | 表示额外信息,例如 Using temporary 表示需要使用临时表存储结果集,常见于排序和分组查询。Using filesort 表示无法利用索引完成的文件排序,这是 ORDER BY 的结果,可以通过合适的索引改进性能。Using index 表示只需要使用索引就可以满足查询表得要求,说明表正在使用覆盖索引。 |
36. 数据库死锁如何解决?
-
死锁是指多个事务在同一资源上相互占用并请求锁定对方占用的资源而导致恶性循环的现象。当多个事务试图以不同顺序锁定资源时就可能会产生死锁,多个事务同时锁定同一个资源时也会产生死锁。
-
为了解决死锁问题,数据库系统实现了各种
死锁检测和死锁超时机制
。越复杂的系统,例如 InnoDB 存储引擎,越能检测到死锁的循环依赖,并立即返回一个错误。这种解决方式很有效,否则死锁会导致出现非常慢的查询。还有一种解决方法,就是当查询的时间达到锁等待超时的设定后放弃锁请求
,这种方式通常来说不太好。InnoDB 目前处理死锁的方法是将持有最少行级排它锁的事务进行回滚。 -
死锁发生之后,只有
部分或者完全回滚其中一个事务,才能打破死锁
。对于事务型系统这是无法避免的,所以应用程序在设计时必须考虑如何处理死锁。大多数情况下只需要重新执行因死锁回滚的事务
即可。
37. 几种索引
- 自适应哈希索引
- 空间索引:
- 全文索引:
- 覆盖索引:
Resource
- https://segmentfault.com/a/1190000013517914
- https://www.cnblogs.com/yyyyfly1/archive/2022/03/11/15993267.html
- https://www.nowcoder.com/discuss/135748
- https://segmentfault.com/a/1190000023827696 redolog, undolog, binlog