B+树的作用总结
- 在磁盘设备上,通过B+树可以有效的存储数据;
- 所有记录都存储在叶子节点上,非叶子(non-leaf)存储索引(keys)信息;而且记录按照索引列的值由小到大排好了序。
- B+树含有非常高的扇出(fanout),通常超过100,在查找一个记录时,可以有效的减少IO操作;
什么是回表
回表指的是,普通索引无法直接定位行记录,因此需要查询两次索引树,第一遍通过普通索引定位到主键id,然后第二遍再通过集聚索引定位到具体行记录,性能相对于只扫描一遍的集聚索引树性能要低一些
mysql 有哪几种锁
行级锁 行级锁是mysql中锁定粒度最细的一种锁
开销大,加锁慢,会出现死锁。发生锁冲突的概率最低,并发度也最高。
表级锁 mysql中锁定粒度最大的一种锁,表示对当前操作的整张表加锁
开销小,加锁快,不会出现死锁。发生锁冲突的概率最高,并发度也最低。
页级锁 页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢
开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
什么是MVCC
多版本的并发控制协议
MVCC的底层实现原理是什么
MVCC实现原理主要是依赖记录中的隐式字段,undo日志,Read View 来实现的。
MySQL三大日志:binlog、redo log和undo log
binlog 记录了对MySQL数据库执行更改的所有的写操作,包括所有对数据库的数据、表结构、索引等等变更的操作。
主要应用场景分别是 主从复制 和 数据恢复。
redo log 是属于引擎层(innodb)的日志,称为重做日志 ,当MySQL服务器意外崩溃或者宕机后,保证已经提交的事务持久化到磁盘中(持久性)。
undo log
记录了数据的逻辑变化
undo log也是MVCC(多版本并发控制)实现的关键
MySQL redo log 与 binlog 的区别
第一:redo log是在InnoDB存储引擎层产生,而binlog是MySQL数据库的上层产生的,并且二进制日志不仅仅针对INNODB存储引擎,MySQL数据库中的任何存储引擎对于数据库的更改都会产生二进制日志。
第二:两种日志记录的内容形式不同。MySQL的binlog是逻辑日志,其记录是对应的SQL语句。而innodb存储引擎层面的重做日志是物理日志。
第三:两种日志与记录写入磁盘的时间点不同,二进制日志只在事务提交完成后进行一次写入。而innodb存储引擎的重做日志在事务进行中不断地被写入,并日志不是随事务提交的顺序进行写入的。
二进制日志仅在事务提交时记录,并且对于每一个事务,仅在事务提交时记录,并且对于每一个事务,仅包含对应事务的一个日志。而对于innodb存储引擎的重做日志,由于其记录是物理操作日志,因此每个事务对应多个日志条目,并且事务的重做日志写入是并发的,并非在事务提交时写入,其在文件中记录的顺序并非是事务开始的顺序。
第四:binlog不是循环使用,在写满或者重启之后,会生成新的binlog文件,redo log是循环使用。
第五:binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。
MySQL InnoDB文件存储结构
InnoDB表由共享表空间文件(ibdata1)、独占表空间文件(ibd)、表结构文件(.frm)、以及日志文件(redo文件等)组成。
MyISAM数据库表文件
test.frm,存储表定义; test.MYD,存储数据; test.MYI,存储索引。
什么是索引
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
一种能帮助mysql提高了查询效率的数据结构:索引数据结构。
索引为什么快
数据存储在磁盘( SSD 跟 CPU 性能也不在一个量级),而磁盘处理数据很慢;
提高磁盘性能主要通过减少 I/O 次数,以及单次 I/O 有效数据量;
索引通过多阶(一个节点保存多个数据,指向多个子节点)使树的结构更矮胖,从而减少 I/O 次数;
索引通过 B+ 树,把业务数据与索引数据分离,来提高单次 I/O 有效数据量,从而减少 I/O 次数;
索引通过树数据的有序和「二分查找」(多阶树可以假设为多分查找),大大缩小查询范围;
索引针对的是单个字段或部分字段,数据量本身比一条记录的数据量要少的多,这样即使通过扫描的方式查询索引也比扫描数据库表本身快的多;
{}和${}的区别是什么?
{}:是预编译处理,可以防止SQL注入
${}:是[字符串替换]
SQL语句优化
避免在索引列上使用IS NULL和IS NOT NULL
对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描
避免在索引列上使用计算
避免select *
避免null 值判断
待续