什么是索引?索引是数据库快速找到记录行的一种数据结构 , 类似我们看书时的目录 , 它是良好性能的关键因素 。尤其是表中的数据量越来越大时 , 如果索引使用不当 , 会严重影响性能 。索引也是最常见的数据库优化手段 , 它能轻易的将查询性能提高好几个量级 。
MySQL索引类型?
mysql索引数据是存储在存储引擎中的 , 所以不同存储引擎中索引的工作方式并不一样 。B-Tree索引:基于B+树(一种多叉搜索数树)来实现的索引类型 , 一般也是使用的最多的索引类型 , 之所以选择B+树而不是其他数据结构 , 是因为B+树在查询时间复杂度可以维持在O(logn)的级别上 , 由于B+的矮胖(从根节点到叶子节点的距离可以维持在较小范围)特性减少磁盘IO次数、数据只存在叶子节点中并且按顺序存储也可以支持快速的范围查询 , 这是其他结构无法满足的!
B+索引中值是按顺序存储的 , 叶子节点到根节点的距离都相同 , 从B+树的根节点开始往下查找 , 节点存储了指向叶子节点的指针 , 通过将要查找的值和每个节点值比较后 , 一层层定位到最终的叶子结点上 , 叶子节点存储的就是行数据、指针或主键 。
假如我们索引列是:
key(lastname(姓),firstname(名),born) , 可以使用B+树索引的查询类型包括:全键值、键值范围、键前缀查找 , 其中键前缀只适用于最左前缀查找:
- 全值匹配:指的是和索引中所有的列进行匹配 , 如可以找到姓名为:Cuba(名) Allen(姓) 、生于1988-10-04的人 , 如where lastname=‘Allen’ and firstname=‘Cuba’ and born='1988-10-04'
- 匹配最左前缀:可以查找姓为Allen的人 , 如where lastname=‘Allen’
- 匹配列前缀:也可以匹配某一列的值的开头部分 , 如where lastname like ‘A%’ 或者where firstname like ‘M%’
- 匹配范围:可以匹配姓在Allen和Bill之间的人
- 精确匹配某一列并匹配另外一列:查找所有姓为Allen、并且名字是以M开头的人 , 如where lastname=‘Allen’ and firstname like ‘M%’
- 访问索引数据:这种查询只需要访问索引本身就行了 , 不需要访问数据行 , 也就是常说的索引覆盖 , 举个例子:如果只需要找到姓为Allen的人的名称 , 而不需要这个人其他的信息 , 名称就存在与索引中 , 不需要再去数据行中查找数据了 。
一般InnoDB查找过程为从辅助索引上开始查找到数据主键 , 然后在主键索引中用主键再次查找 , 最后再找到数据 , 虽然多了一次查找过程 , 但更新数据不会导致聚簇索引频繁变化 。而在MyISAM中不需要2次索引查找 , 因为叶子节点存储的是数据的物理地址可以直接定位 , 虽然查询看似简单了 , 但是物理地址会因为数据频繁变更而发生变化 。
假设有以下数据:
![MySQL是如何利用索引的?](http://img.jiangsulong.com/220425/032H91926-0.jpg)
文章插图
InnoDB(聚簇索引)数据查找过程:
![MySQL是如何利用索引的?](http://img.jiangsulong.com/220425/032H94358-1.jpg)
文章插图
MyISAM(非聚簇索引结构)数据查找过程:
![MySQL是如何利用索引的?](http://img.jiangsulong.com/220425/032H91S5-2.jpg)
文章插图
哈希索引:基于哈希表来实现的索引类型 , 如果存在哈希冲突 , 索引会使用链表来存放多个记录到一个哈希桶中 。举个例子:如果存在以下索引 key USING HASH(firstname) , 哈希索引会使用哈希函数计算出firstname列的哈希值作为key , 并将行指针作为value存储 , 当使用 =、IN()、<=>操作时 , 先计算出sql语句操作查找值的哈希值 , 并使用其来查找哈希表对应的行指针 , 从而返回数据 。
推荐阅读
- mongodb,redis,hbase,三者都是nosql数据库,他们的最大区别和不同定位是什么?
- 如何在基于 Ubuntu 中查看一个软件包的依赖
- 如何快速减臀部赘肉呢?
- 晚上打篮球真的能长高吗
- 怎么锻炼臀部力量比较好
- 怎么可以提臀呢
- 怎样防止运动后长肌肉呢
- 古代卖菜的地方叫什么 古代菜市口是做什么的
- 宋是商朝后代 宋姓的历史
- 曹操一代枭雄旷世人杰 曹操一代枭雄是什么意思