搞懂Mysql InnoDB B+树索引 (2)

  这里我们先假设B+树高为2,即存在一个根节点和若干个叶子节点,那么这棵B+树的存放总记录数为:根节点指针数*单个叶子节点记录行数。假设一行记录的数据大小为1k,那么单个叶子节点(页)中的记录数=16K/1K=16。

  那么现在我们需要计算出非叶子节点能存放多少指针,我们假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,我们一个页中能存放多少这样的单元,其实就代表有多少指针,即16kb/14b=1170。那么可以算出一棵高度为2的B+树,大概能存放1170*16=18720条这样的数据记录。

  根据同样的原理我们可以算出一个高度为3的B+树大概可以存放:1170*1170*16=21902400行数据。所以在InnoDB中B+树高度一般为1-3层,它就能满足千万级的数据存储。在查找数据时一次页的查找代表一次IO,所以通过主键索引查询通常只需要1-3次逻辑IO操作即可查找到数据。

Cardinality值

  如何判断一个索引建立的是否好呢?可以用show index from指令查看Cardinality值,这个值是一个预估值,而不是一个准确值。每次对Cardinality值的统计都是随机取8个叶子节点得到的。

  对于innodb来说,达到以下2点就会重新计算cardinality

如果表中1/16的数据发生变化 

如果stat_modified_counter>200 000 0000

  实际应用中,(Cardinality/行数)应该尽量接近1。如果非常小则要考虑是否需要此索引。实战一下,比如有一张表,我们来show index一下

mysql> show index from Order; +---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Order | 0 | PRIMARY | 1 | id | A | 99552 | NULL | NULL | | BTREE | | | | Order | 1 | IDX_orderId | 1 | orderId | A | 96697 | NULL | NULL | | BTREE | | | | Order | 1 | IDX_productId | 1 | productId | A | 52 | NULL | NULL | | BTREE | | | +---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 3 rows in set (0.00 sec)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwwwp.html