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 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL适合创建索引的11种情况及不适合创建索引的7种情况 -> 正文阅读

[大数据]MySQL适合创建索引的11种情况及不适合创建索引的7种情况

数据准备:

  • 创建学生表和课程表
#创建学生表
CREATE TABLE `student_info`(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`student_id` INT NOT NULL,
`name` VARCHAR(20) DEFAULT NULL,
`course_id` INT NOT NULL,
`class_id` INT(11) DEFAULT NULL,
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

#创建课程表
CREATE TABLE `course`(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`course_id` INT NOT NULL,
`course_name` VARCHAR(40) DEFAULT NULL,
PRIMARY KEY(`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  • 创建俩函数生成随机数和随机字符串
# 创建随机产生字符串函数
DELIMITER //
CREATE FUNCTION RAND_STRING(n INT)
RETURNS VARCHAR(255)
BEGIN
        DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
		DECLARE ret_str VARCHAR(255) DEFAULT '';
		DECLARE i INT DEFAULT 0;
		while i < n DO
				SET ret_str = CONCAT(ret_str,SUBSTRING(chars_str, FLOOR(1 + RAND() * 52), 1));
				SET i = i + 1;
		END WHILE;
		RETURN ret_str;
END //

# 创建随机数函数
DELIMITER //
CREATE FUNCTION rand_num (from_num INT, to_num INT)
RETURNS INT(11)
BEGIN
		DECLARE i INT DEFAULT 0;
		SET i = FLOOR(from_num + RAND() * (to_num - from_num + 1));
		RETURN i;

END //
DELIMETER;
  • 创建随机过程模拟插入数据
#创建插入课程表存储过程
DELIMITER //
CREATE PROCEDURE insert_course(max_num INT)
BEGIN
		DECLARE i INT DEFAULT 0;
		SET autocommit = 0;
		REPEAT
				SET i = i + 1;
				INSERT INTO cours(course_id, course_name)
				VALUES (rand_num(10000, 10100), rand_string(6));
				UNTIL i = max_num
		END REPEAT;
		COMMIT;
END //
DELIMITER;

# 创建插入学生信息存储过程
DELIMITER //
CREATE PROCEDURE insert_stu(max_num INT)
BEGIN
		DECLARE i INT DEFAULT 0;
		SET autocommit = 0;
		REPEAT
				SET i = i + 1;
				INSERT INTO student_info(course_id, class_id, student_id, name)
				VALUES(rand_num(10000, 10100), rand_num(10000, 10200), rand_num(1, 200000), rand_string(6));
				UNTIL i = max_num
		END REPEAT;
		COMMIT;
END//
DELIMITER;
  • 调用存储过程
# 调用存储过程
CALL insert_course(100);
CALL insert_stu(1000000);

哪些情况适合创建索引

  • 字段的数值有唯一性的限制

具有唯一索引的字段,即使是组合字段,也必须建成唯一索引。唯一索引对 insert 的速度损耗可以忽略,但是提高的查找速度是明显的。

  • 频繁作为 where 查询条件的字段

在 student_id 字段上没有索引时查询:耗时235ms

?添加索引:

CREATE INDEX idx_sid ON student_info(student_id);

此时再次查询:,耗时23ms,时间相差十倍左右!所以当某字段经常做 where的查询条件,一定要为其添加索引。

以下每个情况代码验证和以上一样,分别运行有相应索引和没有索引两种情况,比较运行时间。明显可以看出索引可以大大的降低查询时间。一一列举代码略显冗余,所以这里不再赘述代码,只列出剩余的情况及相关说明。

  • ?经常GROUP BY 或 ORDER BY的列

排序后分组或排序自然是非常快了!

  • UPDATE、DELETE 的 WHERE 条件列
  • DISTINCT? 字段需要创建索引

排序后去重自然也更快了!

  • 多表 JOIN 连接操作时,创建索引注意事项

首先,连接表的数量尽量不要超过三张,因为每增加一张表就相当于增加了一次嵌套的循环。数量级增长会非常快,严重影响查询的效率。

其次,对 WHERE 条件创建索引, 因为 WHERE 才是对数据过滤的条件。如果数据量非常大的情况下,没有 WHERE 条件过滤是非常可怕的。

最后,对用于连接的字段创建索引,并且该字段在多张表中的类型必须一致。比如 course_id 在两张表中都为 int(11) 类型,而不能一个为 int 另一个为varchar 类型。

  • 使用列的类型小的创建索引
  • 使用字符串前缀创建索引

在 VARCHAR 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。

  • 区分度高(散列度高)的列适合作为索引
  • 使用越频繁的列要放到联合索引的越左侧
  • 在多个字段都要创建索引的情况下,联合索引优于单值索引

限制索引的数目

在实际工作中,我们也需要注意平衡。索引的数目不是越多越好。我们需要限制每张表上的索引数量,建议单张表索引数量不超过6个,原因如下:

  1. 每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。
  2. 索引会印象 INSERT, DELETE, UPDATE 等语句的性能,因为表中数据更改的同时,索引也会调整和更新,造成负担。
  3. 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估。以生成出一个最好的计划。如果同时有多个索引都可以用于查询时,会增加Mysql优化器生成执行计划时间,降低查询性能。

哪些情况不适合创建索引

  • 在 WHERE 中使用不到的字段,不要设置索引

同理,如GROUP BY 或 ORDER BY 条件里用不到的字段,也不要设置索引。原因也很简单,不需要快速定位,设置索引也没有用!

  • 数据量小的表最好不要使用索引

在数据量很小的时候,原本查询时间已经很短了,不必要再添加索引。索引的回表等操作可能会使耗费时间更多!

  • 有大量重复数据的列上不要建立索引
  • 避免对经常需要更新的表创建过多的索引
  • 不建议用无序的值作为索引
  • 删除不再使用或很少使用的索引
  • 不要定义冗余或者重复的索引

小结

索引是一把双刃剑,可提高查询效率,但也会降低插入和更新的速度并占用磁盘空间。选择索引的最终目的是为了使查询的速度更快,上面给出的原则是最基本的原则。也要结合实际情况来决定是否使用索引!

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:28:13  更:2022-04-09 18:32:21 
 
开发: 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/24 3:21:42-

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