高性能MySQL学习五(B+树索引、哈希索引、全文索引)

1、为什么使用索引索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后读取整个表以查找相关行。表越大,成本越高。但如果表中有相关​​列的索引,MySQL就可以快速确定要在数据文件中间寻找的位置,而无需查看所有数据。这比按顺序读取每一行要快得多。大多数MySQL索引(PRIMARY KEY, UNIQUE,INDEX和 FULLTEXT)存储在B树。例外情况是空间数据...
摘要由CSDN通过智能技术生成

1、为什么使用索引
索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后读取整个表以查找相关行。表越大,成本越高。但如果表中有相关​​列的索引,MySQL就可以快速确定要在数据文件中间寻找的位置,而无需查看所有数据。这比按顺序读取每一行要快得多。
大多数MySQL索引(PRIMARY KEY, UNIQUE,INDEX和 FULLTEXT)存储在B树。例外情况是空间数据类型的索引使用R树,并且该 MEMORY表也​​支持哈希索引。
在这里插入图片描述
2、B+树索引
B+树索引就是传统意义上的索引,这是目前关系型数据库系统中查找最为常用和最为有效的索引。B+树索引的构造类似于二叉树,根据键值(Key Value)快速找到数据。( B+树中的B不是代表二叉 (binary),而是代表平衡(balance), 因为B+树是从最早的平衡二叉树演化而来,但是B+树不是一个二叉树。)
另一个常常被DBA忽视的问题是:B+树索引并不能找到一个给定键值的具体行。B+树索引能找到的只是被查找数据行所在的页。然后数据库通过把页读人到内存,再在内存中进行查找,最后得到要查找的数据。
假设有以下数据表:

mysql> create table people(
    -> last_name varchar(50) not null,
    -> first_name varchar(50) not null,
    -> dob date not null,
    -> gender enum('m','f') not null,
    -> key(last_name,first_name,dob)
    -> )engine=innodb;
Query OK, 0 rows affected (0.05 sec)

该索引组织数据的存储方式如下图所示:
在这里插入图片描述
要注意的是,索引对多个值进行排序的依据是CREATE TABLE 语句中定义索引时列的顺序。看一下最后两个条目,两个人的姓和名都-样,则根据他们的出生日期来排列顺序。

我们插入部分数据来帮助我们实验

mysql> select * from people;
+-----------+------------+------------+--------+
| last_name | first_name | dob        | gender |
+-----------+------------+------------+--------+
| Akroyd    | Christian  | 1958-12-07 | f      |
| Akroyd    | Debbie     | 1990-03-18 | f      |
| Akroyd    | Kirsten    | 1978-11-02 | m      |
| Allen     | Cuba       | 1960-01-02 | m      |
| Allen     | Kim        | 1930-07-12 | m      |
| Allen     | Meryl      | 1980-12-12 | f      |
| Barrymore | Julia      | 2000-05-12 | f      |
+-----------+------------+------------+--------+
7 rows in set (0.01 sec)

这里需要在提到一个MySQL中的语句,EXPLAIN语句,该语句提供了有关SELECT语句执行计划的信息 ,使用也很简单,只要在SELECT语句前加上EXPLAIN即可,显示列信息如下所示。更多可以参见官网EXPLAIN输出格式
在这里插入图片描述
B-Tree索引适用于全键值、键值范围或键前缀查找。其中键前缀查找只适用于根据最左前缀的查找。前面所述的索引对如下类型的查询有效。
在这里插入图片描述
此外,B+Tree通常可以支持“只访问索引的查询”,即查询只需要访问索引,而无须访问;数据行。

  • 后面我们将单独讨论这种“覆盖索引”的优化。
//全值匹配
mysql> select * from people where last_name='Allen' and first_name='Cuba' and dob='1960-01-02';		
+-----------+------------+------------+--------+
| last_name | first_name | dob        | gender |
+-----------+------------+------------+--------+
| Allen     | Cuba       | 1960-01-02 | m      |
+-----------+------------+------------+--------+
1 row in set (0.00 sec)

mysql> explain select * from people where last_name='Allen' and first_name='Cuba' and dob='1960-01-02';
+----+-------------+--------+------+---------------+-----------+---------+-------------------+------+-------------+
| id | select_type | table  | type | possible_keys | key       | key_len | ref               | rows | Extra       |
+----+-------------+--------+------+---------------+-----------+---------+-------------------+------+-------------+
|  1 | SIMPLE      | people | ref  | last_name     | last_name | 107     | const,const,const
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值