MySQL索引相关知识

news2024/11/19 18:36:18

1、什么是索引?

        索引是存储引擎用于提高数据库表的访问速度的一种数据结构。通过给字段​​添加索引​​​可以​​提高数据的读取速度​​​,提高项目的并发能力和抗压能力。​​索引优化​​​时mysql中的一种优化方式。索引的作用相当于​​图书的目录​​​,可以根据目录中的页码​​快速找到所需的内容

2、索引的作用 

        数据是存储在磁盘上的,查询数据时,如果没有索引,会加载所有的数据到内存,依次进行检索,读取磁盘次数较多。有了索引,就不需要加载所有数据,因为B+树的高度一般在2-4层,最多只需要读取2-4次磁盘,查询速度大大提升。

3、索引的优缺点

优点:

  • 加快数据查找的速度
  • 为用来搜索、排序或者是分组的字段添加索引,可以加快搜索、分组和排序的速度
  • 加快表与表之间的连接

缺点:

  • 建立索引需要占用物理空间
  • 会降低表的增删改的效率,因为每次对表记录进行增删改,需要进行动态维护索引,导致增删改时间变长。

4、索引类型有哪些?如何创建索引?

按字段特性分类,MySQL索引按字段特性分类主要分为以下四种:

  • 主键索引(PRIMARY KEY)
  • 唯一索引(UNIQUE)
  • 普通索引(INDEX)
  • 全文索引(FULLTE)

按字段数量还有 联合索引(也叫复合索引、组合索引)

主键索引(PRIMARY KEY)
        建立在主键上的索引被称为主键索引,一张数据表只能有一个主键索引,索引列值不允许有空值,通常在创建表时一起创建。 主键是一种唯一性索引,必须指定为​​PRIMARY KEY​​。

# 修改表时创建
ALTER TABLE tablename ADD PRIMARY KEY(`id`);

#创建表时直接指定
CREATE TABLE `tablename` ( 
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` varchar(255) NOT NULL , 
    PRIMARY KEY (`id`)
);

唯一索引(UNIQUE)
        建立在UNIQUE字段上的索引被称为唯一索引,一张表可以有多个唯一索引,索引列值允许为空,列值中出现多个空值不会发生重复冲突,如果是组合索引,则列值的组合必须唯一。

# 指定了索引名称为realname_index,如果不指定默认就是此字段名
ALTER TABLE table_name ADD UNIQUE INDEX `realname_index`(`realname`);

# 创建表时直接指定
CREATE TABLE `tablename` ( 
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `realname` varchar(20) NOT NULL , 
    UNIQUE realname_index (`realname`)) , 
    PRIMARY KEY (`id`)
);

普通索引(INDEX)
        建立在普通字段上的索引被称为普通索引,是最基本的索引,它没有任何限制。

# 修改表时创建
ALTER TABLE tablename ADD INDEX index_age (`age`);

# 直接创建索引
CREATE INDEX index_age ON tablename(`age`);

# 创建表时直接创建
CREATE TABLE `tablename`(  
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user_id` INT(11),
  `realname` VARCHAR(20),
  `age` INT(3), 
   PRIMARY KEY(`id`),   -- 直接创建主键索引
   UNIQUE index_realname (`realname`) ,   -- 直接创建唯一索引
   INDEX index_age(`age`)            -- 直接创建普通索引
) ENGINE=INNODB CHARSET=utf8mb4;


全文索引(FULLTEXT)

        主要用于查找文本中的关键字,而不是直接比较是否相等,Full-text索引一般使用倒排索引实现,它记录着关键词到其所在文档的映射。

  • 可以通过create table,alter table ,create index创建
  • 目前只有char、varchar,text 列上可以创建全文索引
  • 对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快。
  • ​​MyISAM​​支持全文索引,​​InnoDB​​在mysql5.6之后支持了​​全文索引​​。
  • fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like
  • 全文索引​​不支持中文​​​需要借​​sphinx(coreseek)​​​或​​迅搜<、code>技术处理中文。​
# 修改表结构添加全文索引
ALTER TABLE tablename ADD FULLTEXT index_sheng(`sheng`);

# 直接创建全文索引
CREATE FULLTEXT INDEX index_sheng ON tablename(`sheng`);

# 创建表的时候创建全文索引
CREATE TABLE `tablename`(  
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user_id` INT(11),
  `realname` VARCHAR(20),
  `age` INT(3), 
  `sheng` varchar(30), 
   PRIMARY KEY(`id`),   -- 直接创建主键索引
   UNIQUE index_realname (`realname`) ,   -- 直接创建唯一索引
   INDEX index_age (`age`) ,            -- 直接创建普通索引
   fulltext (`sheng`)  -- 直接创建全文索引
) ENGINE=INNODB CHARSET=utf8mb4;

联合索引 (复合索引、组合索引)

        建立在多个列上的索引被称为联合索引,又叫复合索引、组合索引。在MySQL中使用联合索引时要遵循最左前缀匹配原则。所以我们需要注意如下几个方面:

  • 实际业务场景中创建联合索引时,我们应该把识别度比较高的字段放在前面,提高索引的命中率,充分的利用索引。
  • 创建联合索引后,该索引的任何最左前缀都可以用于查询。比如当你有一个联合索引(col1, col2, col3),该索引的所有最左前缀为(col1)、(col1, col2)、(col1, col2, col3),包含这些列的所有查询都会使用该索引进行查询。
  • 虽然联合索引可以避免回表查询,提高查询速度,但同时也会降低表数据更新的速度。因为联合索引列更新时,MySQL不仅要保存数据,还要维护一下索引文件。所以不要盲目使用,应根据业务需求来创建。
# 修改表结构添加联合索引
ALTER TABLE `tablename_two` ADD INDEX `index_sheng_shi_xian` (`sheng`, `shi`, `xian`);

ALTER TABLE `tablename_two` ADD UNIQUE INDEX `index_sheng_shi_xian` (`sheng`,`shi`, `xian`);

# 触发此索引的查询遵循最左原则
-- 如上最左边的一个字段是sheng, 下面的查询中只有包含sheng字段的查询都会触发。

-- 以下查询都会触发此索引
EXPLAIN SELECT * FROM `tablename` WHERE sheng = '山东省';
EXPLAIN SELECT * FROM `tablename` WHERE sheng = '山东省' AND shi = '菏泽市';
EXPLAIN SELECT * FROM `tablename` WHERE sheng = '山东省' AND shi = '菏泽市' AND xian = '牡丹区';
EXPLAIN SELECT * FROM `tablename` WHERE sheng = '山东省' AND xian = '牡丹区';
EXPLAIN SELECT * FROM `tablename` WHERE xian = '牡丹区' AND sheng = '山东省';   -- 与sheng的查询位置无关,

-- 以下语句不触发,因为没有包含sheng字段的查询
EXPLAIN SELECT * FROM `tablename` WHERE shi = '菏泽市' AND xian = '牡丹区';  -- 不触发

5、如何查看表的所有索引

SHOW INDEXES FROM `表名`;
-- 或
SHOW KEYS FROM `表名`;

-- 查看索引的使用情况
SHOW STATUS LIKE '%Handler_read%';

handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。
handler_read_rnd_next:这个值越高,说明查询低效

6、如何删除索引

DROP INDEX `索引名` ON `表名`;
-- 或
ALTER TABLE `表名` DROP INDEX `索引名`;

7、如何判断索引是否生效?

答:在查询语句前使用Explain
explain函数作用:显示了MYSQL如何使用索引来处理select语句以及连接表。

EXPLAIN SELECT * FROM 表名 WHERE sheng = '山东省';
-- 或者 group by 也会触发索引
EXPLAIN SELECT * FROM 表名 GROUP BY sheng;

Explain 返回的参数如图:
 key字段为null表示未触发索引,有值的未启用的索引。

 Explain 函数返回的参数如下:

 8、哪些情况下索引无效

  1. where 子句中使用 != 或 <> 或 not in 操作符,引擎将放弃使用索引而进行全表扫描。特别地,如果是主键 如 where id > 10 ,这种情况也会走索引。
  2. where 子句中使用 or 来连接条件,or前后条件都包含索引则走索引,or前后只要有一个不包含索引索引失效。
  3. like的模糊查询以 % 开头,索引失效, 如 where title like '%abc' 、where title like '%abc%' 都会导致索引失效,但是 where title like 'abc%'  索引有效 。
  4. 特别的like查询,如果是全覆盖索引,即便是 ‘%abc%’ 也会走索引。 如select * from 表名 where realname like '%abc%' 不走索引, 如果是 select id, realname from 表名 where   realname like '%abc%'   这时就走索引了,(附:索引包含所有满足查询需要的数据的索引,称为覆盖索引(Covering Index)。)
  5. 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不会使用索引,如realname字段是varchar 类型,里面有个123的值,我们使用 where realname = 123 也能擦到数据,但是不会触发索引, 必须使用 where realname = '123'才能使用索引。
  6. 在 where 子句中对字段进行表达式操作,导致引擎放弃使用索引而进行全表扫描。
  7.  在 where 子句中对字段进行函数操作,导致引擎放弃使用索引而进行全表扫描。
  8. 在 where 子句中的 “=” 左边进行函数、算术运算或其他表达式运算,导致系统将可能无法正确使用索引,函数包括ABS,UPPER,DATE,DAY,YEAR等
  9. 对于多列索引,不是使用的一部分,则不会使用索引。
  10. 不适合键值较少的列(重复数据较多的列)。
  11. 字段内容为null,导致索引失效。索引字段上使用is null, is not null,可能导致索引失效
  12. mysql估计使用全表扫描要比使用索引快,则不使用索引

9、 在什么情况下建立索引

  1. 在where查询中经常作为查询条件的字段做索引。
  2. 该字段的内容​​不是唯一的几个值,如性别字段通常只有男、女两个值,不适合使用索引。
  3. 字段内容不是频繁变化的字段适合做索引,更新非常频繁的字段​​​​ 不适合作为索引​​
  4. 不会出现在where子句中​​的字段​​不该创建索引​​

10、为什么我们​​添加完索引​​后​​查询速度为变快​​? 

        传统的查询方法,是按照表的顺序遍历的,不论查询几条数据,mysql需要将表的数据从头到尾遍历一遍。在我们添加完索引之后,mysql一般通过​​BTREE算法​​生成一个​​索引文件​​,在查询数据库时,找到索引文件进行​​遍历(折半查找大幅查询效率)​​,找到相应的键从而获取数据

11、索引的代价

        创建索引是为产生索引文件的,​​占用磁盘空间​​。索引文件是一个​​二叉树类型的文件​​,可想而知我们的dml操作同样也会对索引文件进行修改,所以性能会下降

12、唯一索引比普通索引快吗, 为什么?

唯一索引不一定比普通索引快, 还可能慢

查询时, 在未使用limit 1的情况下, 在匹配到一条数据后, 唯一索引即返回, 普通索引会继续匹配下一条数据, 发现不匹配后返回. 如此看来唯一索引少了一次匹配, 但实际上这个消耗微乎其微.

更新时, 这个情况就比较复杂了. 普通索引将记录放到change buffer中语句就执行完毕了. 而对唯一索引而言, 它必须要校验唯一性, 因此, 必须将数据页读入内存确定没有冲突, 然后才能继续操作. 对于写多读少的情况, 普通索引利用change buffer有效减少了对磁盘的访问次数, 因此普通索引性能要高于唯一索引。

13、MySQL 索引使用有哪些注意事项?

可以从三个维度回答这个问题:索引哪些情况会失效,索引不适合哪些场景,索引规则

索引哪些情况会失效:

  • 查询条件包含or,可能导致索引失效
  • 如果字段类型是字符串,where时一定用引号括起来,否则索引失效
  • like通配符可能导致索引失效。
  • 联合索引,查询时的条件列不是联合索引中的第一个列,索引失效
  • 在索引列上使用mysql的内置函数,索引失效。
  • 对索引列运算(如,+、-、*、/),索引失效。
  • 索引字段上使用(!= 或者 < >,not in)时,可能会导致索引失效。
  • 索引字段上使用is null, is not null,可能导致索引失效。
  • 左连接查询或者右连接查询查询关联的字段编码格式不一样,可能导致索引失效。
  • mysql估计使用全表扫描要比使用索引快,则不使用索引。
  • 后端程序员必备:索引失效的十大杂症

索引不适合哪些场景

  • 数据量少的不适合加索引。

  • 更新比较频繁的也不适合加索引

  • 区分度低的字段不适合加索引(如性别)

索引的一些潜规则

  • 覆盖索引
  • 回表
  • 索引数据结构(B+树)
  • 最左前缀原则
  • 索引下推

14、索引的数据结构有哪些?

        索引的数据结构主要有B+树哈希表,对应的索引分别为B+树索引和哈希索引。InnoDB引擎的索引类型有B+树索引和哈希索引,默认的索引类型为B+树索引

B+树索引(BTREE)

B+ 树是基于B 树和叶子节点顺序访问指针进行实现,它具有B树的平衡性,并且通过顺序访问指针来提高区间查询的性能。
在 B+ 树中,节点中的 key 从左到右递增排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。
进行查找操作时,首先在根节点进行二分查找,找到key所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出key所对应的数据项。MySQL 数据库使用最多的索引类型是BTREE索引,底层基于B+树数据结构来实现。

哈希索引

哈希索引是基于哈希表实现的,对于每一行数据,存储引擎会对索引列进行哈希计算得到哈希码,并且哈希算法要尽量保证不同的列值计算出的哈希码值是不同的,将哈希码的值作为哈希表的key值,将指向数据行的指针作为哈希表的value值。这样查找一个数据的时间复杂度就是O(1),一般多用于精确查找。

15、Hash索引和B+树索引的区别?

  • 哈希索引不支持排序,因为哈希表是无序的。
  • 哈希索引不支持范围查找。
  • 哈希索引不支持模糊查询及多列索引的最左前缀匹配。
  • 因为哈希表中会存在哈希冲突,所以哈希索引的性能是不稳定的,而B+树索引的性能是相对稳定的,每次查询都是从根节点到叶子节点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124746.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文搞懂Linux内核进程原理及系统调用机制

进程四要素 有一段程序代其执行有进程专用的系统堆栈空间在内核有task_struct数据结构进程有独立的存储空间&#xff0c;拥有专有的用户空间 如果具备前三点缺少第四条&#xff0c;称为“线程”&#xff1b;如果完全没有用户空间&#xff0c;称为“内核线程”;如果共享用户空间…

中国剩余定理

最近总是用到中国剩余定理&#xff0c;以前对于这个定理非常的模糊&#xff0c;有时间静下心来简单的学习一下中国剩余定理&#xff0c;文章没有深度&#xff0c;写下这篇博客以作记录。 中国剩余定理CRT前言一、描述二、中国剩余定理求解方法1.除以三余二2.除以五余三3.除以七…

14. UserAgent 反爬是如何实现的,来看看这篇博客

本篇博客实现 【爬虫训练场】 的第一个反爬案例&#xff0c;User-Agent 反爬。 文章目录什么是 User-Agent 反爬在 Python Flask 中实现 User-Agent 反爬什么是 User-Agent 反爬 User-Agent 反爬是一种防止网站被爬虫爬取的技术。 当爬虫向网站发送 HTTP 请求时&#xff0c;会…

初识Kubernetes:(3)Kubernetes资源管理

初识Kubernetes&#xff1a;&#xff08;3&#xff09;Kubernetes资源管理1 资源管理介绍2 YAML语法介绍2.1 YAML语法介绍2.2 YAML语法示例2.2.1 YAML常量2.2.2 对象2.2.3 数组3 资源管理方式3.1 资源管理方式3.2 命令式对象管理3.2.1 kubectl命令3.2.2 操作&#xff08;comman…

操作系统期末考试必会题库2——进程管理

1、某系统出现故障&#xff0c;通过相关指令查看&#xff0c;CPU占有率为0&#xff0c;内存有大量空余&#xff0c;但是用户在其程序中得不到任何相应&#xff0c;请从进程状态分析&#xff0c;当前用户所使用的进程可能是什么状态&#xff08;就绪&#xff0c;运行&#xff0c…

BLE 蓝牙抓包分析

1. 抓包工具 Ellisys & Ellisys Bluetooth Analyzer ​使用方法&#xff1a;https://blog.csdn.net/weixin_44260005/article/details/121216529​ 2. BLE数据样式 3. 数据分析 3.1 ble蓝牙协议栈 3.2 BLE连接过程 http://doc.iotxx.com/BLE%E6%8A%80%E6%9C%AF%E6%8F%AD%…

如何用Alluxio加速云上深度学习训练?

欢迎来到【微直播间】&#xff0c;2min纵览大咖观点 随着企业数据量的不断增加&#xff0c;为了提高深度学习训练的准确性、加快速度并且降低成本&#xff0c;许多企业开始逐步在云上实施分布式训练的方案&#xff0c;本期内容将结合阿里、微软等实际应用案例&#xff0c;分享…

容器安装mysql

1.自己配置仓库和挂载 仓库内容如下 挂载 2.安装工具包 yum install -y yum-utils 3.从阿里云添加docker仓库 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 我们就能查看到 4.cd回主目录开始一系列安装 yum install d…

软件测评师教程之软件测试基础<一>更新中...

目录一.软件测试分类(1)按照开发阶段划分(2)按照测试实施组织划分(3)按照测试技术划分二.软件测试过程模型(1)V模型(2)W模型(3)H模型(4)X模型(5)前置测试模型(6)测试模型的使用三.软件测试策略(1)测试信息流(2)分析设计阶段1.需求说明书评测2.概要设计说明书评测3.详细设计说明…

手绘图说电子元器件-控制与保护器件

控制与保护器件主要包括继电器、开关、接插件和保险器件等,是电子电路中经常使用的器件。 继电器 继电器是一种常用的控制器件,它可以用较小的电流来控制较大的电流,用低电压来控制高电压,用直流电来控制交流电等,并且可实现控制电路与被控电路之间的完全隔离。 继电…

IPV6探测

目录本机是否支持IPv6如何确认一个网站是否开启 IPv6在线工具&#xff1a;IP查询在线工具&#xff1a;IPv6连接测试在线工具&#xff1a;国家IPv6发展监测平台本地工具局域网设备探测pingMSFThc-Ipv6Ipv6-Toolkit端口探测MSFNmap【存在问题】参考领导提了个问题&#xff0c;怎么…

Mybatis 解析mapper过程

Mapper配置的四种方式 配置方法一共有四种&#xff0c; 分别对应四种解析方式&#xff0c;从解析源码可以看出来 private void mapperElement(XNode parent) throws Exception { //添加接口映射器if (parent ! null) {for (XNode child : parent.getChildren()) { //获取所有…

4.7W防削顶单声道D类音频功率放大器HT6872介绍

HT6872简介 HT6872是一款低EMI&#xff0c;防削顶失真&#xff0c;单声道免滤波D类音频功率放大器。在6.5V电源&#xff0c;10%THDN&#xff0c;4Ω负载条件下&#xff0c;输出4.71W功率&#xff0c;在各类音频终端应用中维持高效率并提供AB类放大器的性能。 HT6872的最大特点是…

C++:设计一个保留字(或关键字)的统计程序,从源数据文件(C或C++语言程序)中,读取字符或字符串,与保留字文件中的保留字进行匹配比较,并统计计数。

2.1题目&#xff1a; 设计一个保留字&#xff08;或关键字&#xff09;的统计程序 l建立保留字文件&#xff1b; l从源数据文件&#xff08;C或C语言程序&#xff09;中&#xff0c;读取字符或字符串&#xff0c;与保留字文件中的保留字进行匹配比较&#xff0c;并统计计数。…

python数据分析(1)numpy基础

iamseancheney/python_for_data_analysis_2nd_chinese_version: 《利用Python进行数据分析第2版》 (github.com) NumPy的ndarray&#xff1a;一种多维数组对象 1.性质 NumPy最重要的一个特点就是其N维数组对象&#xff08;即ndarray&#xff09;&#xff0c;该对象是一个快速…

73.qt quick-通用可拖拽表盘示例

截图如下所示: 效果如下所示: 源码已上传至专栏群(第一章底部获取)中,感兴趣的自行下载 demo使用介绍 控件自定义属性已经封装出来了,如下图所示: main.qml如下所示: import QtQuick 2.14 import QtQuick.Window 2.14 import QtQuick.Extras 1.4 import QtQuick.Layouts 1.1…

微信小程序-会议OA项目03

目录 1.Flex布局简介 1.1 什么是flex布局 1.2 flex属性 2.轮播图--组件的使用 3.会议OA项目-首页 1.Flex布局简介 布局的传统解决方案&#xff0c;基于盒状模型&#xff0c;依赖 display属性 position属性 float属性 1.1 什么是flex布局 1) Flex是Flexible Box的缩写&…

攻防世界-fileclude

题目 访问题目场景 阅读php代码 <?php include("flag.php"); highlight_file(__FILE__); if(isset($_GET["file1"]) && isset($_GET["file2"])) {$file1 $_GET["file1"];$file2 $_GET["file2"];if(!empty($f…

法国半导体制造企业RIBER部署MBE技术以支持量子计算

图片来源&#xff1a;网络 法国半导体制造企业RIBER在2022年进一步提升了其在量子处理器耗材市场的发展水平。 早在2021年6月&#xff0c;RIBER已开始部署系统&#xff0c;它在法国图卢兹与 法国国家科学研究中心系统分析与架构实验室&#xff08;LAAS-CNRS&#xff09;创办联合…

Google Guice 1:如何实现依赖注入?

1. 待完善的邮箱程序 1.1 手动注入依赖 前一篇博文《谈谈自己对依赖注入的理解》&#xff0c;笔者只是基于依赖注入的思想&#xff0c;为EmailClient预留了依赖注入的入口 到目前为止&#xff0c;我们只是让dependent class预留了依赖注入的入口&#xff0c;要想实现依赖的自动…