【MySQL】索引 面试题

news2024/12/27 10:36:07

文章目录

      • 适合创建索引的情况
      • 创建索引的注意事项
      • MySQL中不适合创建索引的情况
      • 索引失效的常见情况

在这里插入图片描述

  1. 索引定义与作用

    • 索引是帮助MySQL高效获取数据的有序数据结构,通过维护特定查找算法的数据结构(如B+树),以某种方式引用数据,实现高级查找算法,从而提高数据检索效率,降低数据库IO成本。
    • 例如在查找年龄为45的数据时,无索引需逐条比对,有索引(如二叉树)可减少对比次数,提升效率。
  2. 二叉树与红黑树的不足
    在这里插入图片描述

    • 二叉树:普通二叉树时间复杂度不稳定,可能退化为链表(O(n)),即使相对平衡时为O(log n),也不满足MySQL需求,所以MySQL底层未使用。
    • 红黑树:节点可保证平衡,时间复杂度稳定为O(log n),但数据量大(如1000万数据)时,因其二叉结构节点分叉有限,树会很高,查找需找很多层级,效率不高。
  3. B树的特点
    在这里插入图片描述

    • B树是多岔路平衡查找树,每个节点可有多分支(如度数为五时,最多五个子节点),节点上最多存储一定数量的key(如四个),key有指针指向子节点数据,且存储对应数据。整体为“矮胖”结构,查找层级短,效率高。
  4. B+树的结构与优势

在这里插入图片描述
- 结构优化:在B树基础上优化,更适合外存储索引结构(如InnoDB存储引擎默认采用)。非叶子节点只存储指针,不存储数据,存储压力低;数据只存储在叶子节点,非叶子节点主要起导航作用,便于找到叶子节点数据。
- 磁盘读写代价低:查找数据时,B树需加载路径上节点数据,B+树非叶子节点不存数据,只需通过指针导航找到叶子节点获取数据,无需额外加载非叶子节点数据,效率更高,磁盘读写代价更低。
- 查找效率稳定:所有数据在叶子节点,查找时从根节点依次对比到叶子节点获取数据,查找路径相似,效率稳定。
- 便于扫库和区间查询:叶子节点之间使用双向指针连接,进行范围查询(如查询6 - 34区间数据)时,从根节点找到起始值所在叶子节点后,可利用双向指针一次性获取区间内所有数据,无需多次从根节点查找,效率更高。

  1. 面试题回答要点
    • 索引定义及作用方面:强调索引是有序数据结构,用于高效获取数据,可提高检索效率、降低IO成本(因B+树查找层级短),还能通过索引排序降低数据排序成本,间接降低CPU消耗(创建索引时已排序)。
    • 索引底层数据结构方面:说明MySQL的InnoDB引擎默认采用B+树存储索引,其特点包括阶数多、路径短(性能高)、磁盘读写代价低(非叶子节点只存指针,数据在叶子节点)以及便于扫库和区间查询(叶子节点间双向链表)。

在这里插入图片描述


在MySQL中,合适地创建索引可以显著提高查询性能,但索引也并非越多越好,不当的索引可能会影响数据插入、更新和删除的效率。以下是一些适合创建索引的常见情况:

适合创建索引的情况

  1. 频繁作为查询条件的列:如果某列经常出现在WHERE子句中,作为查询条件,那么为该列创建索引可以加快查询速度。
  2. 经常用于连接(JOIN)操作的列:在多表连接查询中,连接条件列通常应该创建索引,以加速连接操作。例如,在一个订单表和用户表的连接查询中,订单表的用户ID列和用户表的主键列(通常也是用户ID)都应该创建索引,这样可以快速定位匹配的行,提高连接性能。
  3. 在分组(GROUP BY)和排序(ORDER BY)操作中使用的列:当查询需要进行分组或排序操作时,为参与分组和排序的列创建索引可以避免数据库进行额外的排序操作,从而提高查询性能。例如,在查询每个部门的员工数量并按照部门名称排序时,为部门名称列创建索引可以加速分组和排序过程。
  4. 查询返回结果集较小的列:如果一个查询返回的结果集相对较小,但查询条件涉及的列数据量较大,创建索引可以帮助快速定位到满足条件的少量行,从而提高查询效率。例如,在一个包含大量商品信息的表中,根据商品类别查询特定类别下的少数热门商品,为商品类别列创建索引可以快速筛选出相关商品。
  5. 唯一约束列:对于具有唯一性约束的列,数据库通常会自动创建唯一索引,这不仅有助于确保数据的唯一性,还能提高基于该列的查询速度,因为数据库可以直接使用索引快速定位到特定的值。例如,用户表中的用户名或邮箱列,通常需要保证唯一性,并且在用户登录或查询特定用户时,这些列经常被使用,因此创建唯一索引是很有必要的。

创建索引的注意事项

  1. 避免过度索引:每个索引都会占用一定的存储空间,并在数据插入、更新和删除时需要额外的维护成本。如果为太多列创建索引,可能会影响数据库的整体性能,特别是在写操作频繁的表上。因此,只应该为那些真正需要提高查询性能的列创建索引。
  2. 选择合适的数据类型:索引列的数据类型会影响索引的性能。尽量使用简单、占用空间小的数据类型,例如整数类型通常比字符串类型在索引查找上更高效。如果可能的话,对于字符串类型列,可以考虑使用合适的前缀索引,而不是对整个字符串创建索引,以减少索引占用的空间和提高查询性能。
  3. 复合索引的使用:在创建索引时,有时候可以考虑创建复合索引(即包含多个列的索引)。复合索引适用于经常同时根据多个列进行查询的情况。但要注意索引列的顺序,应该将选择性高(即不同值较多)的列放在前面,这样可以更快地缩小查询范围。例如,如果经常根据城市和地区查询用户信息,并且城市的选择性高于地区,那么创建索引时应该先写城市列,再写地区列。
  4. 定期维护索引:随着数据的不断更新和插入,索引可能会变得碎片化,影响查询性能。因此,需要定期对索引进行维护,例如使用OPTIMIZE TABLE语句来重建和优化索引,以确保索引的效率。

MySQL中不适合创建索引的情况

  1. 数据量较小的表:如果表中的数据量非常小,例如只有几十条或几百条记录,全表扫描的速度可能比使用索引更快。因为使用索引需要额外的开销来维护索引结构,在数据量小时,这个开销可能超过索引带来的查询性能提升。例如,一个存储系统配置参数的小表,数据很少变动且查询频率不高,此时创建索引可能得不偿失。
  2. 频繁更新、插入或删除的列:对频繁进行写操作的列创建索引会增加数据库的维护成本。每次数据更新、插入或删除时,数据库都需要更新相关索引,这会影响写操作的性能。例如,在一个记录用户操作日志的表中,操作时间戳列经常更新,若为该列创建索引,会显著降低写操作速度。
  3. 区分度低的列:如果某列的取值非常有限,例如只有“男”“女”两种值,或者大部分值都相同,创建索引的效果可能不佳。因为索引在这种情况下无法有效缩小查询范围,数据库可能仍需扫描大量数据行。例如,一个员工表中的性别列,通常不适合创建索引(除非在特定场景下有特殊需求)。
  4. 数据行数频繁变动且分布不均匀的列:如果列的数据分布极不均匀,且数据行数经常变动,索引可能会频繁进行重新平衡和优化,这会消耗数据库资源。例如,某电商网站订单表中的订单状态列,可能大部分订单处于“已完成”状态,且新订单不断增加,状态频繁更新,此时为该列创建索引可能不利于性能优化。
  5. 长字符串列或大文本列:对于非常长的字符串列(如存储文章内容的列)或大文本列(如存储用户评论的列),创建索引会占用大量的存储空间,并且在查询时比较操作也会消耗较多资源,索引的维护成本较高。通常,只在需要根据这些列进行精确查询且查询频率较高时,才考虑创建索引,且可能更适合使用前缀索引等方式来减少索引大小。
  6. 查询中很少使用的列:如果某列在实际查询中很少被作为查询条件或连接条件使用,那么为其创建索引没有实际意义,反而会增加数据库的存储和维护负担。例如,一个产品表中有一个“产品介绍”列,该列主要用于展示产品详情,很少在查询中用到,就不需要为其创建索引。

索引失效的常见情况

  1. 使用函数或表达式对索引列进行操作:如果在查询条件中对索引列使用了函数(如SUBSTRINGDATE_FORMAT等)或表达式(如age + 1 = 30),索引可能失效。因为索引是基于列的原始值构建的,经过函数或表达式计算后,数据库无法直接使用索引进行快速定位。例如:
SELECT * FROM users WHERE SUBSTRING(name, 1, 3) = 'abc';

在这个查询中,对name列使用了SUBSTRING函数,即使name列有索引,数据库也可能无法有效利用该索引,导致查询效率降低。
2. 隐式类型转换:当查询条件中索引列的数据类型与实际传入的值的数据类型不匹配时,数据库可能会进行隐式类型转换,这可能导致索引失效。例如,如果age列是整数类型,而查询条件写成WHERE age = '30'(传入的是字符串类型),数据库会先将字符串转换为整数再进行比较,这种隐式转换可能使索引无法正常使用。
3. 对索引列进行运算:在查询条件中对索引列进行算术运算(如salary * 2 > 5000),会使索引失效。因为数据库需要先计算表达式的值,然后再进行比较,无法直接利用索引进行快速查找。
4. 使用OR连接多个条件,且其中有索引列和非索引列的条件:如果在WHERE子句中使用OR连接多个条件,并且其中既有索引列的条件又有非索引列的条件,那么索引可能失效。例如:

SELECT * FROM users WHERE age = 30 OR address = 'Beijing';

如果age列有索引,address列没有索引,这个查询可能不会使用age列的索引,因为OR操作使得数据库难以优化查询。
5. LIKE查询以通配符开头:当使用LIKE进行模糊查询时,如果通配符%在查询字符串的开头,索引可能失效。例如:

SELECT * FROM products WHERE product_name LIKE '%phone';

这种查询会导致数据库进行全表扫描,因为索引无法快速定位以通配符开头的数据。
6. 索引列参与了表达式计算或函数调用:与使用函数或表达式对索引列进行操作类似,只要索引列参与了表达式计算或函数调用,索引就可能无法正常工作。例如:

SELECT * FROM orders WHERE YEAR(order_date) = 2023;

这里对order_date列使用了YEAR函数,会使该列的索引失效。
7. IS NULLIS NOT NULL条件对索引列的使用:在某些数据库中,对索引列使用IS NULLIS NOT NULL条件可能导致索引失效,因为索引可能不包含空值的相关信息。不过,有些数据库对这种情况进行了优化,具体是否失效取决于数据库的实现。
8. 索引列使用不等于(!=<>)操作符:如果在查询条件中对索引列使用不等于操作符,数据库可能认为使用索引的成本较高,而选择全表扫描,导致索引失效。例如:

SELECT * FROM employees WHERE salary!= 5000;
  1. 查询条件中的数据分布不均匀导致索引选择不佳:如果索引列的数据分布非常不均匀,例如某一列大部分值都相同,只有少数不同的值,数据库在查询时可能认为使用索引的效果不如全表扫描,从而不使用索引。这种情况相对较少见,但在某些特定的数据场景下可能发生。

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

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

相关文章

Doxygen 使用指南

Doxygen 是一个文档生成工具&#xff0c;可以从源代码中的注释生成高质量的文档&#xff0c;支持多种编程语言&#xff08;如 C/C、Python、Java 等&#xff09;。以下是 Doxygen 的基本使用方法。 1. 安装 Doxygen 1.1 下载 Doxygen 访问 Doxygen 官网。根据操作系统选择合适…

Jensen-Shannon Divergence:定义、性质与应用

一、定义 Jensen-Shannon Divergence&#xff08;JS散度&#xff09;是一种衡量两个概率分布之间差异的方法&#xff0c;它是Kullback-Leibler Divergence&#xff08;KL散度&#xff09;的一种对称形式。JS散度在信息论、机器学习和统计学等领域中具有广泛的应用。 给定两个概…

一个特别的串口通讯

背景 设备是EPICS流式细胞仪&#xff0c;这个设备的控制系统是在DOS系统上的。数据存储在硬盘上&#xff0c;不带串口通讯功能。我们遇到了这个设备后&#xff0c;就开发了一个DOS下的执行程序通过串口&#xff0c;将最新的数据自动上传到服务器上。 编译工具 Turbo C 数据…

4.系统学习-集成学习

集成学习 前言Bias and Variance过拟合&#xff08;overfitting&#xff09;与欠拟合&#xff08;underfitting&#xff09;集成学习为什么有效&#xff1f;Blending 模型集成Stakcing 模型集成Bagging模型集成Bagging 模型集成算法流程&#xff1a;Boosting模型集成作业 前言 …

电商项目高级篇07-redisson分布式锁

redisson分布式锁 1、引入maven依赖2、config类3、可重入锁设计 1、引入maven依赖 <!--引入redisson--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.12.0</version></depend…

Nginx的性能分析与调优简介

Nginx的性能分析与调优简介 一、Nginx的用途二、Nginx负载均衡策略介绍与调优三、其他调优方式简介四、Nginx的性能监控 一、Nginx的用途 ‌Nginx是一种高性能的HTTP和反向代理服务器&#xff0c;最初作为HTTP服务器开发&#xff0c;主要用于服务静态内容如HTML文件、图像、视…

递归算法常见问题(Java)

问题&#xff1a;斐波那契数列,第1项和第2项都为1&#xff0c;后面每一项都为相邻的前俩项的和,求第n个数 解法&#xff1a;每一个数都为前俩个数之和&#xff0c;第1项和第2项都为1&#xff0c;所以写 方法f1(n)即为求第n个数&#xff0c;那么f1(n-1)为求第n-1个数&#xff0…

SpringBoot + HttpSession 自定义生成sessionId

SpringBoot HttpSession 自定义生成sessionId 业务场景实现方案 业务场景 最近在做用户登录过程中&#xff0c;由于默认ID是通过UUID创建的&#xff0c;缺乏足够的安全性&#xff0c;决定要自定义生成 sessionId。 实现方案 正常的获取session方法如下&#xff1a; HttpSe…

【流量、洪水数据下载】网站介绍和下载经验....不断更新!

EarthData 介绍 NASA:链接 数据下载 视频教程:Discover and Access Earth Science Data Using Earthdata Search 数据下载需要注册,已经被卡在邮箱验证上【2024-12-26】… Essential Climate Variables——【The Global Climate Observing System(GCOS) 介绍 其是支…

Pytorch | 利用SMI-FGRM针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用I-FGSSM针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集SMI-FGRM介绍SMI-FGRM算法流程 SMI-FGRM代码实现SMI-FGRM算法实现攻击效果 代码汇总smifgrm.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器&#xff1a; Pytorch | 从零构建AlexNet对CI…

少儿编程在线培训系统:客户服务与学习支持

2.1 VUE技术 VUE它是由HTML代码&#xff0c;配上嵌入在HTML代码里面的Java代码组成的应用于服务器端的语言&#xff0c;使用VUE进行开发能够更加容易区分网页逻辑以及网页设计内容&#xff0c;让程序员开发思路更加清晰化&#xff0c;VUE在设计组件时&#xff0c;它是可以重用的…

流批一体向量化计算引擎 Flex 在蚂蚁的探索和实践

编者按&#xff1a;Flex是蚂蚁数据部自研的一款流批一体的向量化引擎&#xff0c;Flex是Fink和Velox的全称&#xff0c;也是Flexible的前缀&#xff0c;被赋予了灵活可插拔的寓意。本文将重点从向量化技术背景、Flex架构方案和未来规划三个方面展开论述。 作者介绍&#xff1a;…

upload-labs关卡记录11

先上传一个一句话木马试试&#xff0c;居然可以上传成功&#xff0c;复制图片链接&#xff0c;在另一个窗口打开&#xff1a; 会发现&#xff0c;我们明明上传的是shell.php&#xff0c;但是这里就是没有了php,这样我们在执行我们相关的语句的时候就无法执行了&#xff1a; 就…

WebRTC服务质量(08)- 重传机制(05) RTX机制

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…

借助 obdiag,让 OceanBase 参数和变量的对比更简单

本文将介绍 obdiag 工具中参数对比和变量对比功能的适用场景和试用方法。​​​​​​​ obdiag 参数和变量对比功能的适用场景 参数对比功能适用场景 不同observer对于同一参数允许配置不同的值&#xff0c;实际生产环境中&#xff0c;用户可能因多种原因在不同observer上为同…

Net9解决Spire.Pdf替换文字后,文件格式乱掉解决方法

官方文档 https://www.e-iceblue.com/Tutorials/Spire.PDF/Program-Guide/Text/Find-and-replace-text-on-PDF-document-in-C.html C# 在 PDF 中查找替换文本 原文件如下图&#xff0c;替换第一行的新编码&#xff0c;把41230441044替换为41230441000 替换代码如下&#xff…

VBA技术资料MF246:将工作表中形状复制到WORD文档

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

一次医院RIS系统的升级

2020-03-11 目录 数据库升级... 1 数据结构升级... 1 系统配置... 2 WEB服务器准备... 3 启动ASP.NET State Service服务... 3 检查IIS. 4 发布站点... 4 添加应用程序池... 4 发布网站... 5 处理打印模板... 6 web.config的配置... 6 处理图片文件目录... 6 修改W…

显示 Windows 任务栏

显示 Windows 任务栏 1. 取消勾选自动隐藏任务栏2. 重启 Windows 资源管理器References 1. 取消勾选自动隐藏任务栏 Windows 任务栏具有自动隐藏功能&#xff0c;不使用时自动隐藏&#xff0c;使用时显示。 鼠标右键单击桌面上的空白区域&#xff0c;个性化 -> 任务栏。不…

【Unity3D】Jobs、Burst并行计算裁剪Texture3D物体

版本&#xff1a;Unity2019.4.0f1 PackageManager下载Burst插件(1.2.3版本) 利用如下代码&#xff0c;生成一个Texture3D资源&#xff0c;它只能脚本生成&#xff0c;是一个32*32*32的立方体&#xff0c;导出路径记得改下&#xff0c;不然报错。 using UnityEditor; using Uni…