【学习笔记】索引

索引

mysql官方对索引的定义为:索引(index)是帮助Mysql高效获取数据的数据结构

,提取句子主干,就可以得到索引的本质:索引是数据结构。

 

索引的分类

  • 主键索引 (PRIMARY KEY)

    • 唯一的标识,主键不可重复,只能有一个列作为主键

  • 唯一索引 (UNIQUE KEY)

    • 避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引

  • 常规索引 (KEY/INDEX)

    • 默认的,用index或key关键字来设置

  • 全文索引

    • 在特定的数据库引擎下才有,之前是MYISAM,现在INNODB也有了

    • 快速定位数据

 

索引的使用:

  1. 在创建表的时候给字段增加索引

  2. 创建完毕后,增加索引

 

-- 显示所有的索引信息
SHOW INDEX FROM student

image-20221004175315566

 

主键索引和唯一索引的Non_unique都是0,说明它们是唯一的,常规索引是1说明是不唯一的

 

-- 添加一个索引    索引名(列名)
ALTER TABLE `student` ADD FULLTEXT INDEX `studentname`(`studentname`)

这是给student表添加了一个全文索引,索引名为studentname

image-20221004175846425

它的数据类型为FULLTEXT

目前这个全文索引是没有用的,因为数据量太少

 

-- EXPLAIN 分析sql执行的状况
EXPLAIN SELECT * FROM student  -- 非全文索引

image-20221004180200931

 

SELECT * FROM student WHERE MATCH(studentname) against('张')

image-20221004180528189

什么都没有查到,原因是全文索引在数据量比较少的情况下是没有用的

参考博客:(24条消息) 【MySQL优化】——看懂explain_Mandy_i的博客-CSDN博客_explain

 

 

测试索引

我们创建一个表,用循环插入100万条数据,然后查询

首先创建一个user表

-- 创建表
CREATE TABLE `app_user` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT'' COMMENT'用户昵称',
`email` VARCHAR(50) NOT NULL COMMENT'用户邮箱',
`phone` VARCHAR(20) DEFAULT'' COMMENT'手机号',
`gender` TINYINT(4) UNSIGNED DEFAULT '0'COMMENT '性别(0:男;1:女)',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`age` TINYINT(4) DEFAULT'0'  COMMENT '年龄',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT = 'app用户表'

然后插入100万条数据

-- 插入100万数据.
DELIMITER $$
-- 写函数之前必须要写,标志
CREATE FUNCTION mock_data ()
RETURNS INT
BEGIN
    DECLARE num INT DEFAULT 1000000;
    DECLARE i INT DEFAULT 0;
    WHILE i<num DO
        INSERT INTO `app_user`(`name`,`email`,`phone`,`gender`,`password`)VALUES(CONCAT('用户',i),'19224305@qq.com','123456789',FLOOR(RAND()*2),'123456');
        SET i=i+1;
    END WHILE;
    RETURN i;
END;
​
SELECT mock_data ()

插入100万条数据花费142s

 

不添加索引,去查询 ‘用户9999’

SELECT * FROM app_user WHERE `name` = '用户9999'

image-20221004192343864

耗时2.281s

EXPLAIN 查看sql执行过程

EXPLAIN SELECT * FROM app_user WHERE `name` = '用户9999'

image-20221004192457612

可以发现查找了994559 行

 

现在我们给这个字段添加一个索引

-- CREATE INDEX 索引名 ON 表名(字段名)
CREATE INDEX id_app_user_name ON app_user(`name`)

image-20221004192806992

创建索引耗时8.6404s

 

再去查询 ‘用户9999’

SELECT * FROM app_user WHERE `name` = '用户9999'

image-20221004192856776

耗时0.003s

EXPLAIN 查看sql执行过程

EXPLAIN SELECT * FROM app_user WHERE `name` = '用户9999'

image-20221004193001826

只查找了一行

 

对比:

  没有索引 有索引
查询语句时长 2.281s 0.003s
查询语句的行数 994559 1

通过对比,我们发现索引可以大大提升查询的效率

索引在小数据量的时候,用处不大,但是在大数据的时候,区别明显

 

索引原则

  • 索引不是越多越好

  • 不要对进程变动数据加索引

  • 小数据量的表不需要加索引

  • 索引一般加在常用来查询的字段上

 

索引的数据结构

Btree 是Innodb默认的数据结构

参考博客:CodingLabs - MySQL索引背后的数据结构及算法原理

posted @ 2022-10-04 19:44  GrowthRoad  阅读(30)  评论(0编辑  收藏  举报