IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL8.0 函数索引 -> 正文阅读

[大数据]MySQL8.0 函数索引

MySQL8.0 函数索引

MySQL8.0.13 开始支持 在索引中使用函数的值

支持降序索引

支持JSON 数据的索引

函数索引基于虚拟列功能实现

创建表与索引

在 t3 表 上建立索引,创建普通索引和函数的索引

CREATE TABLE `t3` (
  `c1` varchar(10),
  `c2` varchar(10)
);


mysql> create index idx_c1 on t3(c1);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0


-- 创建函数索引
mysql> create index idx_func_c2 on t3( (UPPER(c2)) );
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> explain select * from t3 where upper(c1) = 'ABC' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t3
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using where
1 row in set, 1 warning (0.00 sec)




mysql> explain select * from t3 where upper(c2) = 'ABC' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t3
   partitions: NULL
         type: ref
possible_keys: idx_func_c2
          key: idx_func_c2
      key_len: 43
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.01 sec)

可以看到 c2 这个字段 会走 函数的索引

针对JSON数据 创建索引

json 数据创建索引

CAST(x AS type) 可以将一个数据类型 转化为另一个数据类型。 type 取值有 BINARY, CHAR(n), DATE,TIME, DATETIME,DEMICAL,SIGNED,UNSIGNED 等

mysql> select cast(1100 as char(2));
+-----------------------+
| cast(1100 as char(2)) |
+-----------------------+
| 11                    |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

将 1100 数字 转为字符串类型,结果为 '11'

create table t4(data json, index((CAST(data ->> '$.name' as char(30) ) )));


mysql> show index from t4\G
*************************** 1. row ***************************
        Table: t4
   Non_unique: 1
     Key_name: functional_index
 Seq_in_index: 1
  Column_name: NULL
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment:
      Visible: YES
   Expression: cast(json_unquote(json_extract(`data`,_latin1\'$.name\')) as char(30) charset latin1)
1 row in set (0.00 sec)
                                              

使用 explain 分析 是否可以使用索引.


mysql> explain select * from t4 where CAST(data ->> '$.name' as char(30)) = 'abc' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t4
   partitions: NULL
         type: ref
possible_keys: functional_index
          key: functional_index
      key_len: 33
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

发现可以使用到索引

请添加图片描述

创建一个虚拟列

来给 t3 表 增加一列 ,增加一个虚拟计算列

mysql> alter table t3 add column c3 varchar(10) generated always as (upper(c1));

mysql> select * from t3;
Empty set (0.00 sec)

mysql> insert into t3(c1,c2) values('aa','frank');
Query OK, 1 row affected (0.01 sec)


mysql> select * from t3;
+------+-------+------+
| c1   | c2    | c3   |
+------+-------+------+
| aa   | frank | AA   |
+------+-------+------+
1 row in set (0.00 sec)

创建一个普通的索引 idx_c3

create index idx_c3 on t3(c3);
mysql> explain select * from t3 where c3='aa';
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | t3    | NULL       | ref  | idx_c3        | idx_c3 | 43      | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

此时可以发现就走索引了. 相当于是 建立了一个函数索引

explain select * from t3 where upper(c1)='AAA';

mysql> explain select * from t3 where upper(c1)='AAA';
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | t3    | NULL       | ref  | idx_c3        | idx_c3 | 43      | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+

小问题

有一个 员工表 , id, 奖金 , 薪水 三列, 表结构如下

create table employee(
	id int auto_increment primary key,
	salary int not null,
	bonus int not null
);

经常需要 按照 salary 加上 bonus 的和值 进行查询并且 排序显示,如何设计索引?

create index idx_func on employee((salary + bonus));

show index from employee \G

这样做 是可以使用索引的

mysql> explain select * from employee  where salary + bonus =100 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: employee
   partitions: NULL
         type: ref
possible_keys: idx_func
          key: idx_func
      key_len: 8
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

官方文档例子

example1 指定索引表达式与JSON_UNQUOTE()相同的排序方式

Assign the indexed expression the same collation as JSON_UNQUOTE():

CREATE TABLE employees (
  data JSON,
  INDEX idx ((CAST(data->>"$.name" AS CHAR(30)) COLLATE utf8mb4_bin))
);

INSERT INTO employees VALUES
  ('{ "name": "james", "salary": 9000 }'),
  ('{ "name": "James", "salary": 10000 }'),
  ('{ "name": "Mary", "salary": 12000 }'),
  ('{ "name": "Peter", "salary": 8000 }');
  

SELECT * FROM employees WHERE data->>'$.name' = 'James';


explain SELECT * FROM employees WHERE data->>'$.name' = 'James';


请添加图片描述

The ->> operator is the same as JSON_UNQUOTE(JSON_EXTRACT(...)), and JSON_UNQUOTE() returns a string with collation utf8mb4_bin. The comparison is thus case-sensitive, and only one row matches:

example2 在查询中指定完整的表达式

CREATE TABLE employees (
  data JSON,
  INDEX idx ((CAST(data->>"$.name" AS CHAR(30))))
);


INSERT INTO employees VALUES
  ('{ "name": "james", "salary": 9000 }'),
  ('{ "name": "James", "salary": 10000 }'),
  ('{ "name": "Mary", "salary": 12000 }'),
  ('{ "name": "Peter", "salary": 8000 }');
  
explain SELECT * FROM employees WHERE CAST(data->>'$.name' AS CHAR(30)) = 'James';
 

请添加图片描述

SELECT * FROM employees WHERE CAST(data->>'$.name' AS CHAR(30)) = 'James';

CAST() returns a string with collation utf8mb4_0900_ai_ci, so the comparison case-insensitive and two rows match:

cast() 返回的 字符排序规则 是 utf8mb4_0900_ai_ci ,这个是大小写不敏感的,因此返回了两条数据。

+------------------------------------+
| data                               |
+------------------------------------+
| {"name": "james", "salary": 9000}  |
| {"name": "James", "salary": 10000} |
+------------------------------------+

总结

函数索引的功能 是MySQL8.0 以后才有的功能 ,如果有了这个特性,可以在使用函数的时候 使用这个索引啦,并且还支持JSON 的字段索引,是不是很方便呢?

参考文档

create-index-functional-key-parts

MySQL 8.0 新特性之函数索引

分享快乐,留住感动. '2022-10-16 19:55:36' --frank
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:41:07  更:2022-10-17 12:42:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/20 15:26:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码