today
为什么没有索引查询就慢?
数据在磁盘分布是无序的,分布在各个地方(逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。
存在不同的扇区,分布在不同的磁道。
每查找一次进行一次磁盘io.二叉树也是,每遍历一次数据节点,进行一次IO。
找数据:寻磁道(速度慢,费时),找扇区(速度快),进行磁盘IO,速度很慢。
内存和磁盘是怎么交互的?
内存和硬盘交互的基本单位是页的整数倍,页数有上限,一页一般是4K,一次IO只能读取几页数据,因此mysql一个度一般就是一页,一次查询4K
索引是什么?
索引是数据排好序的数据结构。
索引存储在文件里。
索引结构
二叉树?为什么不用二叉树?当数据量大的时候,节点多,搜索次数多.
红黑树?红黑树,是一种二叉树的变形(会对数据重新排序,避免深度过深),也会存在节点多,搜索次数多(搜索次数多,磁盘IO多)。
HASH?查询效率高,但是不适合使用范围查询
BTREE
B-Tree
度(Degree)-节点的数据存储个数
叶节点具有相同的深度
叶节点的指针为空
节点中的数据key从左到右递增排列
B+tree
为什么用B+树而不用b树呢?
非叶子节点不存储data,只存储key(索引),可以增大度(度增大了,一次性查取出来的数据就多)。
数据存储在叶子节点。
叶子节点之间用指针(范围查找,更加方便,如果查询的数据在多个数据页之间,可以顺序定位到下一个数据页)相连。数据按顺序排序。
B+Tree索引的性能分析
一般使用磁盘I/O次数评价索引结构的优劣
预读:磁盘一般会顺序向后读取一定长度的数据(页的整数倍)放入内存
局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用
B+Tree节点的大小设为等于一个页,每次新建节点直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,就实现了一个节点的载入只需一次I/O
B+Tree的度d一般会超过100,因此h非常小(一般为3到5之间)
度是不是越大越好?
查询一行数据,是把整个数据页查出到内存中(参考上面内存和磁盘是怎么交互的),然后在内存横向查找该节点所要的数据。
因此并不是度越大越好,否则会导致内存不够,同时取出数据也会很久(每次查询几页,数据量大,要查询多次,进行多次IO,所以取数据久)。
数据容量越小,节点存储数据的个数越多,度就越大。
存储引擎是基于表的。
myisam(非聚集索引)
索引文件和数据文件是分离的
叶子节点存储文件指针。
主键索引
非主键索引都是叶子节点存储文件指针。
innodb。
数据文件本身就是索引文件(也叫聚集索引)
主键索引存储的是数据本省
非主键索引存储的是主键索引的值。(字符串存储比较ascii码大小)
innodb为什么一定要有主键?并且推荐使用整型的自增主键?
数据存储在主键索引上。没有主键则系统自动帮忙生产。
自增,插入数据有序,不会导致页分裂。当连续插入的时候可以少分配新的空白页
整型,所需要的空间小。整型比大小,要比字符串比大小快。
为什么主键和非主键存储的值是由这么的区别?
插入数据,由两份数据,浪费空间,还需要考虑数据一致性问题。
联合索引数据长什么样子
varchar:key1+key2+...组成一个key
那不同数据类型的联合索引是怎样的?
索引最左前缀原理?
叶子节点和非叶子节点的区别?
myisam主键索引上存储的是文件指针,而innodb却是数据内容,那innodb没有指针怎么找文件?
猜测:myisam索引文件和数据文件是分离的。innodb索引和文件内容是是存在一起的,不需要指针。