利用散列函数 h , 根据关键字K计算出槽的位置;
不过这样有一个问题就是 两个关键字可能映射到同一个槽上(碰撞) ;
数据库中一般采用最简单的解决方法,即链接法;
链接法中,将同一个槽中的所有元素放在一个链表中;
9.10.2 InnoDB存储引擎中的散列算法
Innodb使用散列算法对字典进行查找;
冲突机制采用链表方式;
散列函数采用除法散列方式;
对于缓冲池页的散列来说,
缓冲池中一个page页都有一个chain指针,指向相同散列函数值的页;
比如当前参数innodb_buffer_pool_size 大小为10MB,则 共有 640x16KB 的页, 对于缓冲池页内存的散列表来说,则需要分配 640*2=1280 个槽,(略大于2倍缓冲页数量的质数), 取比1280略大的质数1399, 则启动时会分配1399个槽的散列表,用来散列查询所在缓冲池中的页;
将要查找的页转换成自然数;
Innodb的表空间都有一个space号, 我们需要查找的应该是某个表空间的某个联系的16Kb的页, 即偏移量offset, Innodb将space左移20位,然后加上这个space和offset,
即关键字 K=space <<20 +space +offset 然后通过除法散列到各个槽中去;
9.10.3 自适应哈希索引
有innodb自己控制,不受DBA或开发人员控制; 不过可以通过参数开启或禁用此特性;
查看自适应哈希索引的情况:
show engine innodb status ;
自适应哈希索引经散列函数映射到一个散列表中, 对于 where index_col = 'xxx' 这种字典类型查找非常快速;
哈希索引只能是等值查询。因为哈希函数映射后就是一个值,就是通过比较值来得到对应的槽。
范围查找是不能使用自适应哈希索引;
9.11 小结
其他
mysql -- show index from tablename 各列解释
show index from table_name
这个命令有助于诊断性能低下的查询,尤其是查询是否使用了可用的索引。
下面介绍下 这个命令显示的结果列的含义:
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
1.Table 表的名称。
2.Non_unique 如果索引不能包括重复词,则为0。如果可以,则为1。
3.Key_name 索引的名称。
4.Seq_in_index 索引中的列序列号,从1开始。
5.Column_name 列名称。
6.Collation 列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。
7.Cardinality
索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。
8.Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。
9.Packed 指示关键字如何被压缩。如果没有被压缩,则为NULL。
10.Null 如果列含有NULL,则含有YES。如果没有,则该列含有NO。
11.Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
12.Comment 多种评注。
参考: https://blog.csdn.net/javamoo/article/details/70184088