高效索引优化:数据库查询提速指南(适合创建索引的11种情况)

事先已经有两张表:course(100条记录),student_info(1000000条记录)

1、字段的数值有唯一性限制

索引自身可以有约束的作用,例如唯一索引、主键索引都可以起到唯一性约束,在数据表中如果某个字段是唯一性的,就可以直接创建唯一性索引或者主键索引,这样可以更快地通过这个索引来确定某条记录。

2、频繁作为WHERE查询条件的字段

在数据量大的情况下某个字段在SELECT语句的WHERE条件中经常被使用到,那么就需要给该字段创建索引,创建普通索引就可以大幅提升数据查询速率

(1)先没有给student_id字段添加索引

sql 复制代码
SELECT course_id,class_id,name,create_time,student_id
FROM student_info
WHERE student_id = 123110; # 0.293s

(2)给student_id字段添加索引

sql 复制代码
SELECT course_id,class_id,name,create_time,student_id
FROM student_info
WHERE student_id = 123110; # 0.029s

3、经常GROUP BY和ORDER BY的列

索引就是为了让数据按照某种顺序进行存储或检索,当使用GROUP BY对数据进行分组或者使用ORDER BY对数据进行排序时,就需要对分组或者排序的字段进行索引。对于多个列的时候,也可以使用组合索引(联合索引)。

(1)student_id字段没有索引

sql 复制代码
SELECT student_id,COUNT(*) AS num
FROM student_info 
GROUP BY student_id
LIMIT 100; # 2.320s

(2)给student_id字段添加索引

sql 复制代码
SELECT student_id,COUNT(*) AS num
FROM student_info 
GROUP BY student_id
LIMIT 100; # 0.026s

如果GROUP BY的字段是student_id,ORDER BY的字段是create_time。此时适合创建联合索引,并且按照(student_id,create_time)这个联合索引顺序的效率最高。

4、UPDATE、DELETE的WHERE条件列

对数据按照某个条件进行查询后再进行UPDATE或DELETE的操作,如果对WHERE字段创建了索引,就能大幅提升效率。原理:需要先根据WHERE条件列检索出来这条记录,然后在对他进行更新或删除。如果进行更新的时候,更新的字段是非索引字段,提升的效率会更明显,这是因为非索引字段更新不需要对索引进行维护。

5、DISTINCT字段需要创建索引

创建索引后能看到SQL查询效率有了提升,同时显示的student_id还是按照递增的顺序进行展示的。这是因为索引会对数据按照某种顺序进行排序。

(1)student_id字段没有索引

sql 复制代码
SELECT DISTINCT(student_id)
FROM student_info; #1.157s

(2)给student_id字段添加索引

sql 复制代码
SELECT DISTINCT(student_id)
FROM student_info; #0.598s

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

①连接表的数量不超过三张,因为每增加一张表就相当于增加了一次嵌套的循环,数量级的增长会很快,对查询效率很不友好;

②对WHERE条件创建索引,因为WHERE才是对数据条件的筛选,这一点在数据量很大的情况下尤为可观;

③对用于连接的字段创建索引,并且该字段在多张表中的类型必须一致

(1)name字段没有索引

sql 复制代码
SELECT student_info.course_id, name, student_info.student_id, course_name
FROM student_info JOIN course
ON student_info.course_id = course.course_id
WHERE name = '462eed7ac6e791292a79'; #0.215s

(2)name字段增加了索引

sql 复制代码
SELECT student_info.course_id, name, student_info.student_id, course_name
FROM student_info JOIN course
ON student_info.course_id = course.course_id
WHERE name = '462eed7ac6e791292a79'; #0.024s

7、使用列的类型小的创建索引

类型小指的就是该类型所表示的数据范围大小,例如TINYINT<MEDIUMINT<INT<BIGINT。

在能满足数据表示的前提之下应当选择较小的类型,这是因为:

  • 数据类型越小,查询时的比较操作就越快;
  • 数据类型越小,索引占用的存储空间就越小,一个数据页可以放下更多的记录,从而可以减少磁盘的I/O,加快读写效率。

这个规则对于主键更加适配,我们知道无论是聚簇索引还是二级索引都会记录主键值,如果主键使用更小的数据类型,就意味着节省更多的存储空间以及更高效的I/O。

8、使用字符串前缀创建索引

如果要对字符串建立索引,而且这个字符串还很长就会有以下问题:

  • B+树索引中的记录要把完整的字符串存储起来,更加费时。并且字符串越长在索引中占用的存储空间就越大;
  • 如果B+树索引中索引列存储的字符串很长,在做比较的时候也会花很长时间。

基于此我们可以建立前缀索引,截取字段前面一部分内容建立索引。根据前缀相同的记录的主键值回表查询完整的字符串值。在阿里的规定中就强制要求了:在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引的长度。

sql 复制代码
# 索引长度计算公式---越接近1越好----一般来说长为20的索引
count(distinct left(列名, 索引长度))/count(*)

9、散列性高的列适合作为索引

列的基数是说经过distinct之后的记录数,在记录行数一定的情况下,列的基数越大,该列中的值越分散;列的基数越小,该列中的值越集中。对列的基数大的列建立索引效果比较好。

sql 复制代码
select count(distinct a)/count(*)
from table;

在联合索引中将区分度高的列放在前面效果好。

10、使用最频繁的列放到联合索引的左侧

由于"最左前缀原则",使用多的列放到左边会增加联合索引的使用率。

11、在多个字段都要创建索引的情况下,联合索引优于单值索引

上面第三条的GROUP BY 和 ORDER BY的例子也可以说明这一点。

索引虽好,但不要过量创建。

相关推荐
l1t1 小时前
DeepSeek总结的无需编译器:编写纯 SQL 的 Postgres 扩展
数据库·sql·postgresql
青山师1 小时前
CompletableFuture深度解析:异步编程范式与源码实现
java·单例模式·面试·性能优化·并发编程
星辰_mya1 小时前
Docker “超级大厨”
运维·docker·容器·面试·架构
【心态好不摆烂】1 小时前
MySQL数据类型
数据库·mysql
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第42题】【JVM篇】第2题:JVM内存模型有哪些组成部分?
java·开发语言·jvm·面试
码云骑士1 小时前
jwt入门介绍
linux·运维·数据库
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第43题】【JVM篇】第3题:GC分为哪两种?Young GC 和 Full GC有什么区别?
java·开发语言·jvm·后端·面试
努力努力再努力wz1 小时前
【Redis 入门系列】为什么需要 Redis?一文串起缓存、分布式、读写分离、分库分表与微服务
数据库·redis·分布式·sql·mysql·缓存·微服务
得闲喝茶1 小时前
SQL处理数据的常用语法语句
数据库·笔记·sql·数据分析·excel