MySQL索引简介(包含索引优化,索引失效,最左前缀简洁版)

一、索引的基本概念

1.什么是索引

   索引是一种数据结构,用于快速查找和访问数据库中的数据。它类似于书本的目录,可以帮助数据库管理系统快速定位到存储数据的位置。通过创建索引,我们可以加快数据库的查询速度并提高系统的性能。索引可以基于一个或多个列,在数据库表中对数据进行逻辑和物理排序,使得查询操作更加高效。

2.索引类型
  1. 主键索引(PRIMARY KEY):每张表只能有一个主键,确保记录的唯一性。
  2. 唯一索引(UNIQUE):确保数据的每一行在索引列上是唯一的。
  3. 普通索引(INDEX):基本的索引类型,没有唯一性的要求,用于加速查询。
  4. 全文索引(FULLTEXT):用于对文本字段进行索引,加快文本搜索操作。
  5. 组合索引(Composite Index):多列值组成一个索引,用于多条件查询。
3.索引原理

MySQL中最常用的索引类型是B-Tree索引。B-Tree索引非常适合处理大量数据的访问。它保持数据有序,允许搜索、插入、删除和顺序访问数据。

4.举例说明

假设我们有一张订单表orders,字段包括order_idcustomer_idorder_date

CREATE TABLE orders (order_id INT AUTO_INCREMENT,customer_id INT,order_date DATE,PRIMARY KEY (order_id)
);

如果我们经常按照customer_id来查询,添加一个索引会是一个很好的选择: 

CREATE INDEX idx_customer_id ON orders (customer_id);

现在,如果执行下面的查询,MySQL就能利用索引快速找到数据。 

SELECT * FROM orders WHERE customer_id = 1001;

二、索引的优化与应用

1.索引的优化

索引虽然可以提高查询性能,但是也不是越多越好。不恰当的索引可能会导致性能问题,以下是几种优化策略:

  1. 选择适当的索引列:选择具有高选择性的列作为索引,这样的列包含很多唯一的值。

  2. 避免冗余索引:如果一个索引是另一个索引的前缀,则可能是多余的。

  3. 使用短索引:对于字符串类型的字段,使用前缀索引可以节省空间和提升性能。

  4. 索引维护:删除不再使用或低效的索引,重新构建碎片化的索引。 

2.优化示例

假设orders表现在非常大,我们注意到customer_idorder_date常常一起出现在查询条件中。为此,我们可以建立组合索引:

CREATE INDEX idx_customer_order ON orders (customer_id, order_date);

这样,任何同时涉及customer_idorder_date的查询都可以利用这个索引。

3.索引优化的原因

优化索引的原要目的包括:

  1. 提高查询效率:使用适当的索引可以减少查询的响应时间。
  2. 减少资源使用:有效的索引可以减少CPU和IO资源的使用。
  3. 提升写操作性能:减少不必要的索引可以加快插入和修改操作。

三、索引的优缺点

1.优点
  • 查询效率提升:这是索引最显著的优点,特别是在大数据量下。
  • 排序和分组加速:索引可以加快ORDER BY和GROUP BY操作。
2.缺点
  • 降低更新表的性能:插入、删除、修改等写操作会导致索引也需要被更新,这将消耗额外的时间。
  • 占用额外的空间:索引虽然能提高读取效率,但同时也会占用磁盘空间。
  • 索引失效:在某些情况下,比如查询中使用了函数或计算,索引可能会失效,导致性能下降。 

四、什么情况下索引失效

  索引可能会失效的情况有很多。下面列举了一些常见的情况,并详细解释了每种情况下为什么索引会失效:

1. 不使用索引列进行查询:

  - 当查询条件没有包含索引列时,数据库可能会选择忽略索引而进行全表扫描。这通常发生在查询使用的是表达式、函数或其他操作,而不是直接使用索引列的原始值。因为索引只会为存储的原始值建立索引,而不会为计算结果或表达式的值建立索引。

2. 使用函数或表达式对索引列进行操作:

 - 当在查询中对索引列使用函数或表达式时,数据库可能无法使用索引进行查找。例如,如果在索引列上使用`LOWER`函数将值转换为小写进行比较,索引将无法提供有效的匹配。这是因为索引只存储原始值,而不存储函数或表达式的结果。

3. 索引列上存在类型转换:

 - 如果查询中的条件需要将索引列进行类型转换,例如将字符串转换为数字进行比较,数据库可能无法使用索引。类型转换可能导致无法利用索引存储的排序顺序,从而使索引失效。

4. 数据不均匀分布或数据重复性高:

 - 当数据在索引列上分布不均匀或存在大量重复值时,索引可能会失效。对于数据不均匀分布的情况,如果查询涉及到的数据存储在索引的某一部分,而其他部分几乎没有被使用,索引将无法提供有效的筛选。对于存在大量重复值的情况,索引可能无法准确地缩小查询范围。

5. 复合索引未按照最佳顺序使用:
   - 当使用复合索引(多列组合的索引)时,查询中的条件未按照最佳顺序使用该复合索引,可能导致索引失效。复合索引的效果通常取决于索引列的顺序。如果查询没有按照索引列的顺序进行筛选,数据库可能无法有效使用索引。

6. 数据表过度索引化:  

- 在某些情况下,如果数据库表被过度索引化,即存在过多的索引,这可能会导致索引失效和性能下降。过多的索引会导致数据库在执行更新操作时需要维护和更新多个索引,从而增加了开销。

此外,过多的索引还会占用额外的存储空间,并且可能会使优化器在选择最佳索引时出现混乱。

7. 数据库统计信息过期: 

- 数据库依赖统计信息来确定查询优化器和索引使用情况。如果统计信息过期或不准确,可能导致索引失效。统计信息包括数据分布、索引列的基数(唯一值的数量)以及索引的选择性等。如果统计信息不准确,查询优化器可能会做出错误的决策,导致索引选择不当。

 总之,为了保持索引的有效性,需要综合考虑查询条件、数据分布、数据类型、查询计划和统计信息等因素,在设计和使用索引时进行细致的权衡和优化。

 五、最左前缀(详解)

我们以一个示例来说明最左前缀原则:

假设我们有一张学生表(students),包含以下字段:student_idfirst_namelast_nameage。我们希望针对first_namelast_nameage字段创建一个组合索引。

CREATE INDEX idx_student_name_age ON students (first_name, last_name, age);

遵循最左前缀原则,这个组合索引可以在以下查询中被有效利用:

  1. 使用first_name进行查询:

SELECT * FROM students WHERE first_name = 'John';

在这个查询中,MySQL可以利用first_name列的索引部分进行快速查找。 

     2.使用first_namelast_name进行查询: 

SELECT * FROM students WHERE first_name = 'John' AND last_name = 'Doe';

 在这个查询中,MySQL可以利用first_namelast_name两个列的索引部分进行查找。

    3.使用first_namelast_nameage进行查询: 

SELECT * FROM students WHERE first_name = 'John' AND last_name = 'Doe' AND age = 25;

在这个查询中,MySQL可以利用整个组合索引进行查找。 

但是,最左前缀原则也意味着当我们只使用索引的后续列或中间列时,索引将不会被有效利用。

例如,如果只使用last_name进行查询:

SELECT * FROM students WHERE last_name = 'Doe';

    虽然存在组合索引 idx_student_name_age,但由于查询中没有使用最左边的列 first_name,MySQL将无法使用这个索引,并且必须执行全表扫描来查找匹配的记录。

综上所述,最左前缀原则告诉我们,在创建组合索引时,应该根据查询频率和查询的列顺序来选择最适合的组合索引。将最常用的列或特定查询条件置于索引的最左边,以确保索引能够最大限度地被利用,提高查询的性能和效率。 

一句话来说 组合索引就是遵从了最左前缀,利用索引中最左边的字段来触发索引,这样的字段称为最左前缀。 

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

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

相关文章

Notepad++ v7.7.1 安装及添加插件

1、notepad_v7.7.1.zip npp.7.7.1.Installer.x64.exe npp.7.7.1.Installer.x86.exe notepad_v7.7.1.ziphttps://www.123pan.com/s/VTMXjv-X6H6v.html 2、notepad插件包_64bit_4.zip ComparePlugin ---->文件对比插件 ComparePlugin.dllNppFTP ---->FTP、FTPES和SFTP …

苹果Mac图像修图软件Photomator和Pixelmator Pro 有什么区别?

同为一个团队设计的Mac修图软件Photomator和Pixelmator Pro有哪些区别呢?有哪些不一样的功能? Photomator和Pixelmator Pro区别如下: 1、用途不同 Photomator 和 Pixelmator Pro 是两个功能强大的应用程序,具有两个不同的用途。…

第8课 将推流端与播放端合并为一对一音视频聊天功能

在第二章的第7课,我们实现了一个推流端,可以把音视频推送到rtmp服务器;在第一章的第4课,我们实现了一个播放器,可以正常播放rtmp音视频流。聪明的你应该可以想到了:把推流端和播放端合并在一起,…

宋仕强论道之华强北的劣势(十八)

华强北微观上的劣势。华强北的企业同质化严重,经营策略和定价方式都差不多,内卷现象突出,价格战、恶性竞争频发,小企业利润空间不断被挤压。如华强北的手机配件市场,很多商户销售相同品牌、相同型号的手机壳、充电器、…

10款以上开源工具,用于大型语言模型应用开发

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

intersection observer实现图片懒加载

图片懒加载(Lazy Load)是一种优化网页性能的技术,它可以延迟图片的加载时间,只有当用户滚动到该图片的位置时才会进行加载。这样可以减少页面的初始加载时间,提高页面的响应速度和用户体验。 以下是使用浏览器原生支持…

skimage图像处理(全)

文章目录 一、简介二、安装三、模块简介:API reference四、项目实战4.1、2D图像处理4.1.1、打印图像属性4.1.2、读取 / 显示 / 保存图像:skimage.io.imread() skimage.io.imshow() skimage.io.imsave()4.1.3、颜色空间转换:skimage.color.r…

LeetCode2807. Insert Greatest Common Divisors in Linked List

文章目录 一、题目二、题解 一、题目 Given the head of a linked list head, in which each node contains an integer value. Between every pair of adjacent nodes, insert a new node with a value equal to the greatest common divisor of them. Return the linked l…

2401d,d理解模板映射

原文 关于映射带模板参数的函数,我惊讶地发现它仍可同运行时确定的函数,甚至是闭包等工作.我想理解它背后的机制. 注释掉的行会导致错误,即编译时无法确定choice(funcs),这是公平的,但它为何与上面两行的func不一样?我猜是因为函数在编译时是可见的字面,但闭包使这可疑. impo…

Python画草莓熊

前言 今天,我们来画草莓熊。 一、草莓熊 草莓熊,英文名Lotso,迪士尼公司和皮克斯动画工作室公司于2010年合作推出的动画片《玩具总动员3》(Toy Story3)的反派角色。Lotso就是大受欢迎的反派"草莓熊"--这是一个特殊的角色&#x…

C#的StringBuilder方法

一、StringBuilder方法 StringBuilder方法Append()向此实例追加指定对象的字符串表示形式。AppendFormat()向此实例追加通过处理复合格式字符串(包含零个或更多格式项)而返回的字符串。 每个格式项都由相应的对象自变量的字符串表示形式替换。AppendJoi…

计算机二级Python选择题考点——公共基础部分

计算机完成一条指令所花费的时间称为一个指令周期。(指令周期越短,指令执行就越快)顺序程序不具有并发性。(具有顺序性、封闭性和可再现性)结构化程序设计强调程序的易读性。系统软件:操作系统、编译程序、数据库管理系统 应用软件:杀毒软件在…

设置docker容器的时区

目录 基于Alpine镜像的Docker容器的Dockerfile中 基于dpkg包管理且使用APT的Linux发行版镜像的docker容器的Dockerfile中 基于Alpine镜像的Docker容器的Dockerfile中 # 替换国内源,可按需添加 RUN set -eux && sed -i s/dl-cdn.alpinelinux.org/mirrors.…

选择 省市区 组件数据 基于vue3 + elment-plus

h5 <el-cascader v-model"form.area" :props"{value: label,label: label }" :options"jsonData" change"handleChange" style"width: 100%;" /> script import jsonData from /utils/city.json; 选完省市区 数据是一…

iview inputNumber有一个默认值1,来看解决方案

iview inputNumber为什么总有一个默认值1&#xff0c;怎么让它为空。 修改编辑没问题&#xff0c;赋值都没问题&#xff0c;但是新增的时候会有默认值1&#xff0c;也没赋值 这种情况你要手动解决&#xff0c;看看当前值有没有被覆盖 我这个问题就是出现覆盖导致的 看代码似乎…

Linux 进程(十) 进程替换

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec*函数以执行另一个程序。当进程调用一种exec*函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec*并不创建新进程,所以调用exec*前…

垂直领域大模型——文档图像大模型的思考与探索

〇、前言 12月1日&#xff0c;2023中国图象图形学学会青年科学家会议在广州召开。超1400名研究人员齐聚一堂&#xff0c;进行学术交流与研讨&#xff0c;共同探索促进图象图形领域“产学研”交流合作。 大会上&#xff0c;合合信息智能技术平台事业部副总经理、高级工程师丁凯博…

C语言编译器(C语言编程软件)完全攻略(第十九部分:VC6.0(VC++6.0)使用教程(使用VC6.0编写C语言程序))

介绍常用C语言编译器的安装、配置和使用。 十九、VC6.0&#xff08;VC6.0&#xff09;使用教程&#xff08;使用VC6.0编写C语言程序&#xff09; Visual C 6.0简称VC或者VC6.0&#xff0c;是微软1998年推出的一款C/C IDE&#xff0c;界面友好&#xff0c;调试功能强大。VC6.0…

iOS苹果和Android安卓测试APP应用程序的区别差异

在移动应用开发中&#xff0c;测试是一个至关重要的环节。无论是iOS苹果还是Android安卓&#xff0c;测试APP应用程序都需要注意一些差异和细节。本文将详细介绍iOS和Android的测试差异&#xff0c;包括操作系统版本、设备适配、测试工具和测试策略&#xff0c;并回答一些新手容…

1.5 Unity中的数据存储 PlayerPrefs、XML、JSON

Unity中的三种数据存储&#xff1a;数据存储也称为数据持久化 一、PlayerPrefs PlayerPrefs是Unity引擎自身提供的一个用于本地持久化保存与读取的类&#xff0c;以键值对的形式将数据保存在文件中&#xff0c;然后程序可以根据关键字提取数值。 PlayerPrefs类支持3种数据类…