B+树索引的使用

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

什么时候使用B+树索引

   并不是在所有的查询条件下出现的列都需要添加索引。对于什么时候添加B+树索引,我的经验是访问表中很少一部分时,使用B+树索引才有意义。对于性别字段,地区字段,类型字段,它们可取值的范围很小,即低选着性。如:

   select * from student WHERE sex = 'M'

对于性别,可取值的范围只有'M','F'。对上述SQL语句得到的结果可能是该表的50%的数据,这时添加B+树索引时完全没有必要的。相反,如果某个字段的取值范围很广,几乎没有重复,即高选择性,即此时使用B+树索引时做合适的,例如姓名字段,基本上在一个应用中都不允许重名的出现。

   因此,当访问高选择性字段并从表中取出很少一部分时,对这个字段添加B+树索引是非常有必要的。但是如果出现了访问字段是高选择性的,但是取出的行数据占用表中大部分的数据时,这时MySQL数据库就不会使用B+树索引了,我们先来看一个例子:

mysql> show index from info\G;

*************************** 1. row ***************************

        Table: info

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 356639

     Sub_part: NULL

       Packed: NULL

         Null: 

   Index_type: BTREE

      Comment: 

Index_comment: 

*************************** 2. row ***************************

        Table: info

   Non_unique: 1

     Key_name: index_link_family

 Seq_in_index: 1

  Column_name: link_family

    Collation: A

  Cardinality: 9385

     Sub_part: 255

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment: 

Index_comment: 

*************************** 3. row ***************************

        Table: info

   Non_unique: 1

     Key_name: index_date

 Seq_in_index: 1

  Column_name: date

    Collation: A

  Cardinality: 356639

     Sub_part: NULL

       Packed: NULL

         Null: 

   Index_type: BTREE

      Comment: 

Index_comment: 

      表info大约有50万行数据。info表上的date字段,该字段是日期类型,字段上有一个index_date的非唯一索引。我们来看下面两条SQL的执行:

 

mysql> explain  select * from info where date = '2006-07-26 15:56:01'\G;

*************************** 1. row ***************************

           id: 1

  select_type: SIMPLE

        table: info

         type: ref

possible_keys: index_date

          key: index_date

      key_len: 8

          ref: const

         rows: 2

        Extra: 

1 row in set (0.00 sec)

 

ERROR: 

No query specified

可以看到使用了index_date这个索引,这也符合我们前面提到的高选择性,选取表中很少行的原则。但是如果执行下面这条语句:

 

 

mysql> explain  select * from info where date > '2006-07-26 15:56:01'\G;

*************************** 1. row ***************************

           id: 1

  select_type: SIMPLE

        table: info

         type: ALL

possible_keys: index_date

          key: NULL

      key_len: NULL

          ref: NULL

         rows: 356639

        Extra: Using where

1 row in set (0.00 sec)

可以看到possible_keys依然是index_date,但是实际优化器使用的索引key显示的是NULL。为什么?因为这不符合我们前面说的原则,虽然date这个字段的值是高选择性的,但是我们取出的行占用了表中很大一部分。

 

mysql>   select @a:=count(id) from info where date > '2006-07-26 15:56:01';

+---------------+

| @a:=count(id) |

+---------------+

|        452549 |

+---------------+

1 row in set (0.18 sec)

 

mysql> select @b:=count(id) from info ;

+---------------+

| @b:=count(id) |

+---------------+

|        452554 |

+---------------+

1 row in set (0.11 sec)

 

mysql> select @a/@b;

+--------+

| @a/@b  |

+--------+

| 1.0000 |

+--------+

1 row in set (0.00 sec)

可以看到我们将取出行的数大概是表的100%的行,因此优化器没有选择使用索引。Mysql数据库的优化器会通过EXPLAIN的rows字段预估查询可能得到的行,如果大于某一个值,则B+树会选择全表的扫描。至于这个值,根据我的经验一般在20%。即当取出的数据量超过表中数据的20%,优化器就不会使用索引,而是进行全表的扫表。

但是预估的返回行数的值是不准确的,可以看到优化器判断日期小于2006-07-26的行为356639,而实际的是452549 。

有时优化器的选择并不完全是正确的,有时你更应该相信自己的判断(可以通过force index(index_name)来执行判断两条语句执行的时间差别)。










本文转自 kuchuli 51CTO博客,原文链接:http://blog.51cto.com/lgdvsehome/1174516,如需转载请自行联系原作者
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
存储 数据库 索引
B树与B+树的区别
B树与B+树的区别
|
8月前
|
存储 数据库 索引
为什么索引底层用b+树不用b树
为什么索引底层用b+树不用b树
57 0
|
8月前
|
索引
一次区分 B树、B+树,B*树
一次区分 B树、B+树,B*树
57 0
|
9月前
|
存储 数据库 索引
B树和B+树的区别是什么呢?
B树和B+树的区别是什么呢?
82 0
|
9月前
|
存储 数据库 索引
数据库索引采用B+树不采用B树的原因
磁盘块读写效率更高:B+树相比于B树,在磁盘块的读写上具有更好的性能。B+树内部的非叶子节点只存储键值信息,而不包含具体的数据记录,这使得每个磁盘块能够存储更多的键值对。同时,由于叶子节点间使用链表进行连接,可以通过顺序读取的方式快速扫描整个索引。因此,B+树在进行磁盘块的读写操作时,具有更高的效率。
75 0
|
9月前
|
存储 关系型数据库 MySQL
为什么MySQL索引使用B+树而不用hash表和B树
支持范围查询:B+树索引在数据结构上有序排列,可以有效支持范围查询,例如大于、小于、区间查询等操作。而哈希表无法支持范围查询,只能进行精确查找,而B树在范围查询操作时性能相对较低。
158 0
|
4月前
|
存储 SQL 关系型数据库
InnoDB主键索引树和二级索引树
InnoDB主键索引树和二级索引树
42 0
InnoDB主键索引树和二级索引树
|
4月前
|
存储 关系型数据库 索引
MyISAM主键索引树和二级索引树
MyISAM主键索引树和二级索引树
32 0
MyISAM主键索引树和二级索引树
|
8月前
|
存储 关系型数据库 MySQL
为什么MySQL索引结构采用B+树?
一位6年经验的小伙伴去字节面试的时候被问到这样一个问题,为什么MySQL索引结构要采用B+树?这位小伙伴从来就没有思考过这个问题。只因为现在都这么卷,后面还特意查了很多资料,他也希望听听我的见解。
101 0
|
算法 索引
【数据结构】动态查找表— B-树和B+树
【数据结构】动态查找表— B-树和B+树
153 0
【数据结构】动态查找表— B-树和B+树

热门文章

最新文章