MYSQL 性能优化 index 函数,隐藏,前缀,hash 索引 使用方法(2)

9eabce33634885e0c700914d63e50669.png

接着上期说,MYSQL 8 的索引的方式相对MYSQL 5.7 有了很多的进步,其中最突出的就是添加的functional indexes , 那么这个功能到底是什么时候开始的有的。

8.013 ,对MYSQL 8.013版本中开始添加了函数索引,下面我们举一个例子

create table function_test (id bigint primary key auto_increment,
                            name varchar(20) not null,
                            birth_day datetime);

c2f7c585a57250e2b7e0bbd71bc87f8b.png

mysql> insert into function_test (name,birrth_day) values ('Tim','2018-09-09');
Query OK, 1 row affected (0.01 sec)

mysql> insert into function_test (name,birrth_day) values ('Sam','2020-01-09');
Query OK, 1 row affected (0.01 sec)

mysql> insert into function_test (name,birrth_day) values ('Pam','2021-01-09');
Query OK, 1 row affected (0.00 sec)

Alter table function_test add index month(birrth_day);

70d7efa5c0f7bc7433688894c3cebf57.png

实际上我们得到了一个带有函数的索引
CREATE TABLE `function_test` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `birrth_day` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `month` (`birrth_day`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |

explain select birrth_day from function_test where month(birrth_day) = 5;

explain select birrth_day from function_test where month(birrth_day) = 5;

801c83b9f20cc2e7c2b902a9c5b70d0d.png

基于这个功能,MYSQL的的版本应该是在8.013 版本以上。

而前缀索引是MYSQL独有的功能,但使用时有场景的,也就是首先添加前缀索引的额类型是字符类型,通过字段前部分的字段的值就可以明细查找数据,其主要的目的就是减少索引字节的同时,还能提高效率。

我们举例

create  table prefix_test (id bigint primary key auto_increment,name varchar(20) not null, type_comments varchar(2000));

1d6a668b55be7fc97a78222597bc2d03.png

ed457a737f34a442194f36385e2c4e00.png

mysql> insert into prefix_test (name,type_comments) values ('Tim','1_我不喜欢');
Query OK, 1 row affected (0.01 sec)

mysql> insert into prefix_test (name,type_comments) values ('Sam','3_我很喜欢');
Query OK, 1 row affected (0.01 sec)

mysql> insert into prefix_test (name,type_comments) values ('Semon','2_没感觉');
Query OK, 1 row affected (0.00 sec)

mysql> alter table prefix_test add index (type_comments(1));
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

explain select name from prefix_test where type_comments like '1%';


通过上面的例子也可以看出,实际上我们只需要给2000 字符的,中的一个1个字符建立索引,就可以完成某些快速查找的完成。

191675bbe89c16b46032608a38cc909f.png

或者可以通过这样的方式进行GROUP BY  等方式的数据组织等。

在这些过后就是MYSQL 的隐藏索引,这个并不是一个新的功能,在其他数据库也有类似的索引类型,实际上隐藏索引是针对某些查询来验证索引的有效性,并且让他上线或者下线的功能。

b3cfafb99301d5086ee5e3f4d5e886f4.png

mysql>
mysql> alter table prefix_test add index (type_comments(1)) invisible;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table prefix_test;
                                                                                                                                                                                      
CREATE TABLE `prefix_test` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `type_comments` varchar(2000) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `type_comments` (`type_comments`(1)) /*!80000 INVISIBLE */
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |



mysql> explain select name from prefix_test where type_comments like '1%';

| id | select_type | table       | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |

|  1 | SIMPLE      | prefix_test | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |

1 row in set, 1 warning (0.00 sec)

上面的图中可以展示出虽然建立了新的索引但是invisible 的状态是无法使用的。如果要是要使用可以立即让他进入到 visible的状态。

最后是hash 索引,在上一篇中提到了自己建立了HASH 的方式解决等值索引中的多个字段建立联合索引,我们下面举一个例子来看看如何操作。

mysql> alter table hash_test add hash_col varchar(20) generated always as (crc32(concat(type1,type2)));
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select * from hash_test;
+----+------+-------+-------+------------+
| id | name | type1 | type2 | hash_col   |
+----+------+-------+-------+------------+
|  1 | Tim  | 10    | 20    | 2249310613 |
+----+------+-------+-------+------------+
1 row in set (0.00 sec)

mysql> insert into hash_test (name,type1,type2) values ('Sam','20','30');
Query OK, 1 row affected (0.00 sec)

mysql> select * from hash_test;
+----+------+-------+-------+------------+
| id | name | type1 | type2 | hash_col   |
+----+------+-------+-------+------------+
|  1 | Tim  | 10    | 20    | 2249310613 |
|  2 | Sam  | 20    | 30    | 2378129210 |
+----+------+-------+-------+------------+
2 rows in set (0.00 sec)

b5005a94222c07e75054e87091010d2b.png

下面我们就可以给hash 的虚拟字段建立索引

2d1575e58ab3777c83d184e3f591a84f.png

那么下次我们下次在查询的时候,就可以直接使用hash_col 来作为查找的索引字段,而不再关心ytype1 type2 如果有50个字段要建立索引,那么也可以不管,就一个字段可以表达N 个字段的值,这样查询速度快,同时你的索引任何时刻只有一个,空间效率的问题都解决了。

923668d41e824431383036b23cd91111.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值