高级数据库学习

2020-04-04  本文已影响0人  抬头挺胸才算活着

参考资料:
[1]. What does eq_ref and ref types mean in MySQL explain
[2]. MySQL 是怎样运行的:从根儿上理解 MySQL
[3]. 超全面MySQL语句加锁分析(上篇)(求转)
[4]. 超全面MySQL语句加锁分析(中篇)(求转)
[5]. 超全面MySQL语句加锁分析(下篇)(求转)

B+树索引

索引是为了快速查找记录,针对数据页做的简易目录就叫做索引。key,是对应页的所有记录中最小的主键值,page_no是没有必要从小到大连续的,页已经根据目录项的顺序在逻辑上连续了,前面的页的记录都小于后面页的记录,这样我们查找的时候首先在索引上进行二分法查找到页的位置,然后再在页里根据槽再进行二分查找。



上面的方法带来了两个问题:
1.记录非常多的情况下,页的数量也非常多,索引的数量也非常多。
2.删除页的时候删除掉目录项,因为索引是用数组来表示的,需要移动较多的元素。
因此索引页根数据一样用页来存储,每条索引页当做记录一样。



当记录太多的时候,用多个索引页来存放索引

索引页为了快速查找也需要进行索引,这样就变成了嵌套目录了...



于是这样就变成了B+树,树的非叶子节点是数据页的索引,叶子节点是数据页。

表空间可以看做一个内存池,区是连续的页,所以是为了数据能够连续存储而设置的存储概念。

IN子查询

IN查询的时候会先把子查询建立为临时表(可能放在内存,也看放在硬盘),然后设置索引,再去查主查询。这样是为了防止内存不够,建立索引也可以加快主查询。IN的时候我们会想到用哈希来做比较快,所以临时表建在内存的时候,索引也是建的哈希索引。
建立了临时表之后,接下来两个表进行查询的时候实际上可以转化为内连接,可以转而用内连接的优化方法来进行优化查询。
既然可以转化为内连接,那么一开始能不能不建立临时表,直接进行内连接呢?但是直接连接后第一个表会重复多次,而且我们只在乎这边的记录是否有对应的存在在另外一个表中,因为我们是用IN,所以我们提出了下面半连接的概念。
将s1表和s2表进行半连接的意思就是:对于s1表的某条记录来说,我们只关心在s2表中是否存在与之匹配的记录,而不关心具体有多少条记录与之匹配,最终的结果集中只保留s1表的记录。半连接是MYSQL内部的概念。
下面这两句是相同的

SELECT * FROM s1 
    WHERE key1 IN (SELECT common_field FROM s2 WHERE key3 = 'a');

半连接

SELECT s1.* FROM s1 SEMI JOIN s2
    ON s1.key1 = s2.common_field
    WHERE key3 = 'a';
IS IX
S 兼容 不兼容
X 不兼容 不兼容

IS和IX之间都是标志,表示真正的锁,所以都是互相兼容的。

IS IX
IS 兼容 兼容
IX 兼容 兼容

学生在教学楼门口加IS锁时,是不关心教学楼门口是否有IX锁的,维修工在教学楼门口加IX锁时,是不关心教学楼门口是否有IS锁或者其他IX锁的。IS和IX锁只是为了判断当前时间教学楼里有没有被占用的教室用的,也就是在对教学楼加S锁或者X锁时才会用到。

韦恩图的意思要读懂:
A与B圆相交,从左到右分别是
A.key 独有
A.key and B.key 都有
B.key 独有
然后将这些拿去join
以左上角的图为例,A left join B的意思就是,A的全部加上A和B的共同部分key。
左下的图,在左连接的基础上去掉中间部分,然后取B.key为null部分,中间部分B肯定不为null,因为是A.key和B.key共有的部分。
最下面全部都有的这张图,语法上因为没有full outer join,所以可以用union (distinct)把左连接和右连接组合起来。



上一篇下一篇

猜你喜欢

热点阅读