Skip to content

Commit 7c9006f

Browse files
committed
mysql
1 parent 1923617 commit 7c9006f

File tree

1 file changed

+2
-19
lines changed

1 file changed

+2
-19
lines changed

MD/数据库-MySQL.md

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,29 +42,16 @@ MyISAM相对简单所以在效率上要优于InnoDB。如果系统插入和查
4242
## 锁表、锁行
4343
[https://segmentfault.com/a/1190000012773157](https://segmentfault.com/a/1190000012773157)
4444

45-
### 何时锁
46-
4745
### 悲观锁乐观锁、如何写对应的SQL
4846
[https://www.jianshu.com/p/f5ff017db62a](https://www.jianshu.com/p/f5ff017db62a)
4947

5048
### 索引
5149
#### 原理
5250
我们拿出一本新华字典,它的目录实际上就是一种索引:非聚集索引。我们可以通过目录迅速定位我们要查的字。而字典的内容部分一般都是按照拼音排序的,这实际上又是一种索引:聚集索引。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
5351

54-
主要使用[B+树](https://www.jianshu.com/p/3a1377883742)来构建索引,为什么不用二叉树是因为:第一,B+树是多叉的,可以减少树的高度。第二,索引本身较大,不会全部存储在内存中,会以索引文件的形式存储在磁盘上,然后是因为[局部性原理](https://www.cnblogs.com/xyxxs/p/4440187.html),数据库系统巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入,(由于节点中有若干个数组,所以地址连续)。而红黑树这种结构,深度更深。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性。
55-
56-
在InnoDB里,每个页默认16KB,假设索引的是8B的long型数据,每个key后有个页号4B,还有6B的其他数据(参考《MySQL技术内幕:InnoDB存储引擎》P193的页面数据),那么每个页的扇出系数为16KB/(8B+4B+6B)≈1000,即每个页可以索引1000个key。在高度h=3时,s=1000^3=10亿!!也就是说,InnoDB通过三次索引页的I/O,即可索引10亿的key。通常来说,索引树的高度在2~4。
57-
#### 分析
58-
好处:
59-
60-
1. 快速取数据
61-
2. 唯一性索引能保证数据记录的唯一性
62-
3. 实现表与表之间的参照完整性
52+
使用B+树来构建索引,为什么不用二叉树?红黑树在磁盘上的查询性能远不如B+树。原因是红黑树最多只有两个子节点,所以高度会非常高,导致遍历查询的次数会多,又因为红黑树在数组中存储的方式,导致逻辑上很近的父节点与子节点可能在物理上很远,导致无法使用磁盘预读的局部性原理,需要很多次IO才能找到磁盘上的数据;但B+树一个节点中可以存储很多个索引的key,且将大小设置为一个页,一次磁盘IO就能读取很多个key,且叶子节点之间还加上了下个叶子节点的指针,遍历索引也会很快。
6353

64-
缺点:
65-
66-
1. 索引需要占物理空间。
67-
2. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。
54+
B+树的高度如何计算?在Linux里,每个页默认4KB,假设索引的是8B的long型数据,每个key后有个页号4B,还有6B的其他数据(参考《MySQL技术内幕:InnoDB存储引擎》P193的页面数据),那么每个页的扇出系数为4KB/(8B+4B+6B)=256,即每个页可以索引245个key。在高度h=3时,s=256^3=16777216。通常来说,索引树的高度在2~4。
6855

6956
#### 优化
7057
如何选择合适的列建立索引?
@@ -87,9 +74,5 @@ MyISAM相对简单所以在效率上要优于InnoDB。如果系统插入和查
8774
1. 事务问题。在执行分库之后,由于数据存储到了不同的库上,数据库事务管理出现了困难。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。
8875
2. 跨库跨表的join问题。在执行了分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上,我们无法join位于不同分库的表,也无法join分表粒度不同的表,结果原本一次查询能够完成的业务,可能需要多次查询才能完成。
8976
3. 额外的数据管理负担和数据运算压力。额外的数据管理负担,最显而易见的就是数据的定位问题和数据的增删改查的重复执行问题,这些都可以通过应用程序解决,但必然引起额外的逻辑运算。
90-
### 缓存
91-
对于很多的数据库系统都能够缓存执行计划,对于完全相同的sql, 可以使用已经已经存在的执行计划,从而跳过解析和生成执行计划的过程。MYSQL提供了更为高级的查询结果缓存功能,对于完全相同的SQL (字符串完全相同且大小写敏感) 可以执行返回查询结果
92-
93-
MySQL缓存机制简单的说就是缓存sql文本及查询结果,如果运行相同的sql,服务器直接从缓存中取到结果,而不需要再去解析和执行sql。如果表更改 了,那么使用这个表的所有缓冲查询将不再有效,查询缓存值的相关条目被清空。更改指的是表中任何数据或是结构的改变,包括INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等,也包括那些映射到改变了的表的使用MERGE表的查询。显然,这对于频繁更新的表,查询缓存是不适合的,而对于一些不常改变数据且有 大量相同sql查询的表,查询缓存会节约很大的性能。
9477

9578
欢迎光临[91Code](http://www.91code.info/?utm_source=github&utm_medium=github),发现更多技术资源~

0 commit comments

Comments
 (0)