1. MySQL中的主键是B+树,Mongo中的主键是B树(有些地方写作B-树,这不叫做B减树,还是B树的意思)。 为什么两个数据库选择不一样呢?①B树和B+树的区别在于,B树的内部节点上也会存储有数据data,但是B+树所有的data都存储在叶子节点上,同时,叶子结点上还有指向右边叶子结点的指针。结构的不同造成查询的时间复杂度不同。B树的查询复杂度最好为O(1),而B+树则有稳定的查询时间复杂度,为O(LogN),但是B+树支持范围遍历查询。②Mongo为非关系型数据库,更强调的是单个数据的查询,所以选择了B树,而sql是关系型数据库,要更多的支持范围查询,所以选择了B+树。 但是不管B树还是B+树,都用到了磁盘预读性原理,大大减少了磁盘IO的次数。2. MySQL中的聚集索引和非聚集索引 ①对于MyISAM的非聚集索引表来说,表数据和索引是分成两部分存储的,主键索引和二级索引存储上没有任何区别。使用的是B+树作为索引的存储结构,所有的节点都是索引,叶子节点存储的是索引+指向索引对应的记录的数据的指针。 ②对于聚集索引表来说,表数据是和主键一起存储的,主键索引的叶结点存储行数据(包含了主键值),其他列,事务ID,回滚指针,二级索引的叶结点存储行的主键值。使用的是B+树作为索引的存储结构,非叶子节点都是索引关键字,但非叶子节点中的关键字中不存储对应记录的具体内容或内容地址。叶子节点上的数据是主键与具体记录(数据内容)聚集索引的优点: 1.当你需要取出一定范围内的数据时,用聚集索引也比用非聚集索引好。

2.当通过聚集索引查找目标数据时理论上比非聚集索引要快,因为非聚集索引定位到对应主键时还要多一次目标记录寻址,即多一次I/O。

3.使用覆盖索引扫描的查询可以直接使用页节点中的主键值。

聚集索引的缺点: 1.随机插入容易造成页分裂,按照主键的顺序插入是最快的方式,否则将会出现页分裂(就是存储数据行的内存页容量不够,需要新申请一个内存页分担一部分数据行),影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键。

2.更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。

3.二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。

二级索引的叶节点存储的是主键值,而不是行指针(非聚集索引存储的是指针或者说是地址),这是为了减少当出现行移动或数据页分裂时二级索引的维护工作,但会让二级索引占用更多的空间。

4.采用聚集索引插入新值比采用非聚集索引插入新值的速度要慢很多,因为插入要保证主键不能重复,判断主键不能重复,采用的方式在不同的索引下面会有很大的性能差距,聚集索引遍历所有的叶子节点,非聚集索引也判断所有的叶子节点,但是聚集索引的叶子节点除了带有主键还有记录值,记录的大小往往比主键要大的多。这样就会导致聚集索引在判定新记录携带的主键是否重复时进行昂贵的I/O代价。

Mongodb 主键的选择 mongodb主键问题_mysql

3. MySQL的联合索引和覆盖索引 联合索引就是多列索引,就是可以多个字段建立一个索引,并且是最左前缀匹配元素

create index a_b_c on user(a,b,c)
这样相当于是创建三个索引
a
a,b
a,b,c

①最左前缀匹配原则,MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如 a=“3” and="" b=“4” c="">5 and d=6,如果建立(a,b,c,d)顺序的索引,d是无法使用索引的,如果建立(a,b,d,c)的索引则都可以使用到,a、b、d的顺序可以任意调整。 ②=和in可以乱序,比如 a=1 and b=2 and c=3 建立(a,b,c)索引可以任意顺序,MySQL的查询优化器会帮你优化成索引可以识别的形式。我自己写了篇更相信的索引相关知识可以再看看这个博客,列举了我博客里的部分情况联合索引覆盖索引: 就是假如有一个联合索引(a,b,c),如果我们只是需要a,b,c这几个字段的数据,查询时就不需要根据主键id去聚集索引里面回表查询了。