第五章

作者: frankie_cheung | 来源:发表于2020-10-29 13:55 被阅读0次
mysql b+树索引基础

作者在索引基础讲了一些废话,关于索引的基础,看下图足以。

image.png
b+树索引作者列举的一些信息

示例表:

Create Table: CREATE TABLE `people` (
  `last_name` varchar(50) NOT NULL,
  `first_name` varchar(50) NOT NULL,
  `dob` date NOT NULL,
  KEY `last_name` (`last_name`,`first_name`,`dob`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
mysql> select * from people;
+-----------+------------+------------+
| last_name | first_name | dob        |
+-----------+------------+------------+
| bob       | kk         | 1997-12-24 |
| frankie   | cheung     | 1998-12-24 |
| hhhaa     | erkk       | 1996-12-24 |
+-----------+------------+------------+
3 rows in set (0.00 sec)

以下均为可以使用索引的案例

  • 全值匹配:按照索引的顺序全部都使用索引
mysql> explain select * from people where last_name='bob' and first_name='kk' and dob='1997-12-24';
+----+-------------+--------+------------+------+---------------+-----------+---------+-------------------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key       | key_len | ref               | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------------------+------+----------+-------------+
|  1 | SIMPLE      | people | NULL       | ref  | last_name     | last_name | 407     | const,const,const |    1 |   100.00 | Using index |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------------------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
  • 最左匹配
mysql> explain select * from people where last_name='bob';
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | people | NULL       | ref  | last_name     | last_name | 202     | const |    1 |   100.00 | Using index |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql>

  • 匹配列前缀
mysql> explain select * from people where last_name like '%b';
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key       | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | people | NULL       | index | NULL          | last_name | 407     | NULL |    3 |    33.33 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
  • 匹配范围值
mysql> explain select * from people where last_name >='bob' and last_name <='frankie' ;
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key       | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | people | NULL       | range | last_name     | last_name | 202     | NULL |    2 |   100.00 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
  • 精确匹配某一列且模糊匹配领一列
mysql> explain select * from people where last_name ='bob' and first_name like '%k' ;
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+
| id | select_type | table  | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra                    |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+
|  1 | SIMPLE      | people | NULL       | ref  | last_name     | last_name | 202     | const |    1 |    33.33 | Using where; Using index |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
  • 覆盖索引:注意Extra中的Using index
mysql> explain select last_name from people where last_name ='bob' ;
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | people | NULL       | ref  | last_name     | last_name | 202     | const |    1 |   100.00 | Using index |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

因为索引是有序的,所以假如你可以使用上述方式,则那你也可以进行排序

b+树索引的限制
  • 不使用最左匹配原则
    如下方式其实是走索引的
mysql> explain select last_name from people where first_name ='kk' ;
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key       | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | people | NULL       | index | NULL          | last_name | 407     | NULL |    3 |    33.33 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
其他索引

作者又开始介绍了哈希索引,空间数据索引R-TREE,全文索引,因为基本不使用,所以直接略过

索引的优点
  • 减少扫描量
  • 避免排序和临时表
  • 随机IO变顺序IO

作者在此介绍了一种索引评价规则:三星系统
1.索引把相关信息放到一起。则一星,这里的放到一起 我个人理解为多列索引组合的
2.索引的数据顺序和查询顺序一直。则二星 这里就是要按照顺序where条件
3.覆盖索引 则三星

高性能索引策略
  • 独立的列
    其实就是不要隐式转换,不要在索引列使用函数,例如date_format 不用表达式 不要进行字段转换。

  • 字段的前缀做索引
    例如 有个字段是email 其实后缀差不多,所以索引创建为 index2(email(6) 对于每个记录都是只取前 6 个字节。

  • 索引选择性
    索引的选择性指的是不重复的索引值和总count的比例
    索引值=distinc(col)/count()
    该值处于1/count(
    )和1之间,该值越高则,查询效率越高。
    唯一索引(主键索引)该值为1,性能最好
    为什么如此呢?因为一个字段不同的值约多,索引就更加高效的排除一些无用数据。

  • 多列索引
    不要在表中查询的每个字段都创建一个单独的索引,非常浪费磁盘空间,建议创建多列索引。上述也试验过多列索引,where 只使用某个列依然可以使用到索引。

  • 将选择性最高的字段放在索引的最前面
    假如创建的是组合索引,那么那些字段在前,那些字段在后 这肯定会影响查询效率,本书中讲的是选择性最高的放前面。

  • 聚簇索引
    其实聚簇索引相当于主键索引,但是聚簇索引要比主键索引大,因为规则如下:
    1.假如你创建的表有主键索引,则聚簇索引就是主键索引。
    2.假如你没有主键索引,则按照你创建索引的顺序,找到第一个unique索引,来作为聚簇索引
    3.假如上述都没有,则MySQL会自己产生一个聚簇索引GEN_CLUST_INDEX,该索引以行id为索引列,就是大家平时听说的,假如没主键,依然会创建一个虚拟主键的过程。
    聚簇索引在同一个表有且只有一个。
    reference:https://www.mysqltutorial.org/mysql-index/mysql-clustered-index/

  • 覆盖索引
    想象一下,假如你在翻看一本书的目录,只需要查看章节的名称,你肯定不需要到章节对应的页数查看,因为章节名称在目录上就有。

相关文章

网友评论

    本文标题:第五章

    本文链接:https://www.haomeiwen.com/subject/fevkvktx.html