首页 > 数据库 >【数据库】详解MySQL数据库索引

【数据库】详解MySQL数据库索引

时间:2025-01-20 21:57:57浏览次数:3  
标签:index 数据库 MySQL 查询 索引 详解 SQL SELECT

目录

1.介绍

2.索引概述

2.1.优缺点

3.索引结构

3.1.B+Tree索引

3.2.Hash索引

4.索引分类

5.索引语法

5.1.创建索引

5.2.查看索引

5.3.删除索引

6.SQL性能分析

6.1.慢查询日志

6.2.profile详情

6.3.explain执行计划

7.索引使用

7.1索引使用原则

7.1.1.最左前缀法则

7.1.2.索引失效情况

7.2.SQL提示

7.3.覆盖索引

7.4.前缀索引

7.5.单列索引与联合索引

8.索引设计原则


1.介绍

索引是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引

2.索引概述

2.1.优缺点

优势:

  • 提高数据检索的效率,降低数据库的IO成本

  • 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗

劣势:

  • 索引列占用空间(磁盘中的ibd文件、MYI文件)

  • 索引提高查询效率的同时也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE时,效率降低

3.索引结构

索引是在第三层,存储引擎层实现的。根据存储引擎的不同,索引的结构也会有所不同

  • B+Tree索引

最常见的索引类型,大部分引擎都支持B+树索引

  • Hash索引

底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询

  • R-tree(空间索引)

空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少

  • Full-text(全文索引)

是一种通过建立倒排索引,快速匹配文档的方式。类似于Lucene、Solr、ES

3.1.B+Tree索引

我们重点研究InnoDB引擎的B+树存储结构

这是经典的的B+Tree

相对于B-Tree的区别是:

  1. 所有的数据都会出现在叶子节点

  2. 叶子节点形成一个单向链表

B+Tree

MySQL索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能

3.2.Hash索引

哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中

如果多个键值映射到相同的槽位上,它们就产生了hash冲突(hash碰撞),可以通过链表解决

Hash索引的特点:

  1. Hash索引只能用于对等比较(=、in),不支持范围查询(between、>、<)

  2. 无法利用索引完成排序操作

  3. 查询效率高,通常只需要一次检索就可以了,效率通常要高于B+Tree索引

不同存储引擎对hash索引的支持情况:

在MySQL中,仅Memory引擎支持hash索引。但InnoDB具有自适应hash功能,hash索引是存储引擎根据B+Tree索引在指定条件下自动构建的

4.索引分类

在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种

聚集索引的存取规则:

  • 如果存在主键,主键索引就是聚集索引

  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引

  • 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引

聚集索引的叶子节点下面挂着这一行的数据

二级索引的叶子节点下面挂着id

回表查询

先到二级索引查找对应的主键值,再回到聚集索引根据主键值查找对应的行数据数据

5.索引语法

5.1.创建索引

CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name (index_col_name, ...);

括号中的内容为表中的字段,一个索引是可以关联多个字段的,如果一个索引只关联一个字段,这种索引称为单列索引,如果关联多个字段,这种索引称为联合索引或组合索引

5.2.查看索引

SHOW INDEX FROM table_name

5.3.删除索引

DROP INDEX index_name ON table_name;

6.SQL性能分析

为了进行SQL优化(主要优化查询语句),我们学习SQL性能分析

SQL执行频率

SQL优化对增删改的作用微乎其微,我们首先要分析增删改查在当前数据库所占的比例

通过如下指令,我们可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次

SHOW [session][global] STATUS LIKE 'Com_______';

一个下划线就代表一个字符

操作与对应次数

如果发现当前数据库的操作中查询占据了绝大部分,我们就要对当前数据库进行优化

我们要优化哪些语句呢?

可以通过慢查询日志定位SQL语句

6.1.慢查询日志

慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志

MySQL的慢查询日志默认没有开启,需要在MySQL的配置文件(/etc/my.cnf)中配置信息

  • 查询慢查询日志开启状态

SHOW VARIABLES LIKE 'slow_query_log';

  • 添加配置信息

打开my.cnf配置文件,添加如下配置

#开启MySQL慢日志查询开关
slow_query_log=1
#设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就被视为慢查询,记录慢查询日志
long_query_time=2

配置完毕之后,通过以下指令重新启动MySQL服务器进行测试

systemctl restart mysqld

查看慢日志文件中记录的信息 /var/lib/mysql/local-slow.log

6.2.profile详情

在慢查询中记录的SQL语句是执行过程中耗时超过了预设的指定时间之后才会记录,比如预设的指定时间是2秒,超过了2秒才会记录在慢查询日志当中。加入某些SQL语句耗时1.8秒,这样的语句是不会记录在慢查询日志当中的。加入一些语句的业务很简单,但是执行达到了1.9秒,那这样的SQL性能也是较低的,我们需要定位到这样的SQL。

可以借助profile详情定位

SHOW PROFILES;

SHOW PROFILES能够在做SQL优化时帮助我们了解时间都耗费到哪里去了。通过have_profiling参数,能够看到当前MySQL是否支持profile操作:

SELECT @@have_profiling;

默认profiling是关闭的,可以通过set语句在session/global级别开启profiling;

SET profiling=1;

6.3.explain执行计划

EXPLAIN或者DESC命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序

语法:

#直接在select语句之前加上关键字explain/desc
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件;

EXPLAIN执行计划各字段含义:

  • id

select查询的序列号,表示查询中执行select子句或者是操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行)

  • select_type

表示SELECT的类型,常见的取值有SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(SELECT/WHERE之后包含了子查询)等

  • type

表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、index、all

  • possible_key

显示可能应用在这张表上的索引,一个或多个

  • Key

实际使用的索引,如果为NULL,则没有使用索引

  • Key_len

表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好

  • rows

MySQL认为必须要执行查询的行数,在InnoDB引擎的表中,是一个估计值,可能并不总是准确的

  • filtered

表示返回结果的行数占需读取行数的百分比,filtered的值越大越好

7.索引使用

7.1索引使用原则

7.1.1.最左前缀法则

如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列

如果跳过某一列,索引将部分失效(后面的字段索引失效)

7.1.2.索引失效情况
  • 范围查询

联合索引中,出现范围查询(>、<),范围查询右侧的列索引失效。如果使用>=、<=则右侧不会失效

  • 索引列运算

不要在索引列上进行运算操作,这将导致索引失效

  • 字符串不加引号

字符串类型字段使用时不加引号,这将导致索引失效

  • 模糊查询

如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效

  • or连接的条件

用or分隔开的条件,如果or的一侧的列有索引,而另一侧的列没有索引,那么涉及的索引都不会被用到

  • 数据分布影响

如果MySQL评估使用索引比全表更慢,则不使用索引

7.2.SQL提示

SQL提示是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优化的目的

use index:建议使用

EXPLAIN SELECT * FROM tb_user USE index(idx_user_pro) WHERE profession='软件工程';

ignore index:禁止使用

EXPLAIN SELECT * FROM tb_user IGNORE index(idx_user_pro_age_sta) WHERE profession='软件工程';

force index:强制使用

EXPLAIN SELECT * FROM tb_user FORCE index(idx_user_pro_age_sta) WHERE profession='软件工程';

7.3.覆盖索引

尽量使用覆盖索引(查询过程中使用了索引,并且查询需要返回的列在该索引中已经全部能够找到字段值),减少select *的使用

select *极易出现回表查询的情况

using index condition:查找使用了索引,但是需要回表查询数据

using where; using index:查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据

7.4.前缀索引

当字段类型为字符串(varchar,text等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率。此时可以只将字符串的一部分前缀建立索引,这样可以大大节约索引空间,从而提高索引效率

CREATE INDEX idx_xxxx ON table_name(colum(n));

n为10则提取前10个字符

  • 前缀长度

可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值,索引选择性越高则查询效率越高,唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的

SELECT COUNT(distinct email)/COUNT(*) FROM tb_user;
SELECT COUNT(distinct substring(email,1,5))/COUNT(*) FROM tb_user;

7.5.单列索引与联合索引

单列索引:一个索引只包含单个列

联合索引:一个索引包含了多个列

在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引,而非单列索引

多条联合查询时,MySQL优化器会评估哪个字段的索引效率更高,会选择该索引完成本次查询

8.索引设计原则

  1. 针对数据量较大,且查询比较频繁的表建立索引

  2. 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引

  3. 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高

  4. 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引

  5. 尽量使用联合索引,减少单列索引,查询时联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率

  6. 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率

  7. 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每一列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询

标签:index,数据库,MySQL,查询,索引,详解,SQL,SELECT
From: https://blog.csdn.net/2302_78914800/article/details/145268914

相关文章

  • Mysql的学习
    Mysql建立索引优化:sql优化:为了解决下面的索引失效问题序列索引优化:解决orderby的关键在于提前在索引中就给好排序解决limit优化:利用id的子查询解决了回表查询然后提升了效能。关于count()的优化:`关于COUNT()的效率问题:COUNT()是用来统计记录数量的函数。不同写法的......
  • 【C++提高篇】—— C++泛型编程之模板基本语法和使用的详解
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、模板的概念二、函数模板2.1函数模板的使用2.2函数模板注意事项2.3普通函数与函数模板的区别2.4普通函数与函数模板的调用规则2.5模板的局限性三、类模板3.1类模板的使用3.2类模板......
  • 【Java毕设】基于java的火车订票管理系统设计新版源码+数据库+说明+LW
    一、项目介绍本论文主要论述了如何使用JAVA语言开发一个火车订票管理系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述火车订票管理系统的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程,对系......
  • JSP某医学院实习管理系统7s3pv--程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表技术要求:开发语言:JSP前端使用:HTML5,CSS,JSP动态网页技术后端使用SpringBoot,Spring技术主数据库使用MySQL开题报告内容一、研究背景与意义随着医学教育的快......
  • JSP明星周边在线购物商城zzfnj(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表技术要求:开发语言:JSP前端使用:HTML5,CSS,JSP动态网页技术后端使用SpringBoot,Spring技术主数据库使用MySQL开题报告内容一、课题背景及意义随着互联网技术......
  • JSP民族服饰文化数字化展示系统cyi8g程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、课题名称民族服饰文化数字化展示系统二、研究目的与意义本课题旨在探索民族服饰文化的数字化展示方法,通过构建数字化展示系统,将传统民族服饰......
  • JSP民宿短租系统an01j(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表技术要求:开发语言:JSP前端使用:HTML5,CSS,JSP动态网页技术后端使用SpringBoot,Spring技术主数据库使用MySQL开题报告内容一、研究背景与意义随着互联网技术的......
  • 查询SQL数据库
    问题希望从数据库获取一些数据。解决方案使用PDO::query()向数据库发送SQL查询,然后利用一个foreach循环获取每行结果。向数据库发送查询//设置数据库连接所需的用户名$user='admin';//设置数据库连接所需的密码$password='123456';//创建一个PDO实例来连接到MySQL......
  • 阳振坤:AI 大模型的基础是数据,AI越发达,数据库价值越大
    2024年1月12日,第四届OceanBase数据库大赛决赛在北京圆满落幕。在大赛的颁奖典礼上,OceanBase首席科学家阳振坤老师为同学们献上了一场主题为“爱上数据库”的公开课,他不仅分享了个人的成长历程,还阐述了对数据库行业现状与未来的见解和思考。阳老师回忆了自己年轻时,与如今的同......
  • JAVA开源毕业设计 在线课程管理系统 Vue.JS+SpringBoot+MySQL
    本文项目编号T137,文末自助获取源码\color{red}{T137,文末自助获取源码}......