MySQL索引详解

索引

在MySQL中,查询方式可以根据访问表数据的方式分为两种:全表扫描和使用索引。

  1. 全表扫描(Full Table Scan):

    • 全表扫描是指在查询过程中,MySQL会遍历整个表的每一行来检查满足查询条件的数据。
    • 当查询条件无法利用索引或没有适当的索引可用时,MySQL将执行全表扫描。
    • 全表扫描可以处理表中的所有行,但在大型表或查询复杂度较高的情况下可能导致较慢的查询速度。
  2. 使用索引(Index Scan):

    • 索引是一种数据结构,用于加速查询操作。MySQL使用B-tree索引来存储和管理数据。
    • 当查询条件能够匹配索引列,并且存在适当的索引可用时,MySQL可以使用索引来快速定位满足条件的行。
    • 索引扫描可以避免全表扫描,减少查询所需的I/O和处理时间,从而提高查询性能。

在实际情况中,MySQL会根据查询条件、表的大小和索引的使用情况来选择最合适的查询方式。以下是一些关于查询方式的详细点:

  • 全表扫描适用于以下情况:

    • 查询条件无法利用索引,例如使用不等于(<>)操作符、模糊匹配的LIKE操作等。
    • 表的规模相对较小,全表扫描的性能仍然可以接受。
  • 使用索引适用于以下情况:

    • 查询条件能够匹配索引列,例如使用等于(=)操作符、范围查询等。
    • 表的规模较大,使用索引可以大幅减少查询时间。
    • 查询中涉及到多个列的筛选和排序。

请注意以下几点:

  • 索引并非总是万能的,有时候错误的索引设计可能导致性能下降。
  • 适当的索引设计和维护可以显著提高查询性能,但过多的索引或不必要的索引可能会增加写操作的开销和存储空间占用。
  • 索引会随着内容的变化而变化
  • 缺点: 创建索引,更新索引 ,需要消耗额外的资源(cpu,磁盘,内存等)

问题

索引是建立在库,还是表上?如果是表上的,建立在表的什么上?

​ 索引是建立在表里的字段上的,也就是索引是根据字段里的内容建立的

哪些字段上适合建立索引?

数据比较大的表,经常查询使用的字段,字段里出现重复率不高的内容

innodb支持的索引

InnoDB是MySQL数据库中一种常用的存储引擎,支持多种类型的索引用于提高查询性能。下面是InnoDB支持的一些常见索引类型的详细介绍:

  1. B-tree索引(B树索引):
    B-tree索引是InnoDB中最常见的索引类型。它使用B-tree数据结构来组织索引数据。B-tree索引适用于精确匹配和范围查询,能够快速定位数据。B-tree索引支持从左到右的前缀匹配查询,可以用于优化模糊查询。在InnoDB中,主键索引就是一种特殊的B-tree索引。

  2. 全文索引:
    全文索引用于快速搜索文本内容,而不只是单词的匹配。InnoDB支持全文索引,可以对包含文本的列进行全文索引的创建。全文索引能够实现更复杂的文本搜索,例如关键字搜索、词语组合等。在InnoDB中,全文索引使用倒排索引的数据结构来实现。

  3. 哈希索引:
    哈希索引是一种高效的索引类型,适用于等值查询。它使用哈希函数将索引值映射到索引项,因此能够快速定位数据。InnoDB支持哈希索引,但仅适用于内存表(MEMORY表)。哈希索引不支持范围查询和排序操作,因为哈希函数是基于索引值的完整匹配。

  4. 主键索引:
    主键索引是一种特殊的索引类型,用于唯一标识表中的每一行。在InnoDB中,如果表定义了主键(PRIMARY KEY),则主键索引会自动创建。主键索引的值是唯一的,因此可以用于快速查找特定行。主键索引还可以用作外键关系的参考。

  5. 外键索引:
    外键索引是一种用于实现表之间关系的索引类型。它定义了表与表之间的引用关系,确保数据的完整性和一致性。外键索引基于外键关系建立,并指向关联表的主键索引。通过外键索引,可以方便地进行表之间的关联查询和级联操作。

这些索引类型在InnoDB中具有不同的特点和适用场景。根据具体的查询需求和数据特征,选择适合的索引类型可以提高数据库的查询性能和数据操作效率。

innodb结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0rIazJ7t-1689612649202)(D:\Snipaste\03【电脑截图软件】snipaste截图软件\Typora\mysql\日志\innodb图.png)]

hash和b-tree

在InnoDB存储引擎中,支持两种类型的索引:B-tree索引和哈希索引。这些索引具有不同的特点和用途。

B-tree索引:

  • B-tree索引是InnoDB默认的索引类型。它使用B-tree数据结构进行组织和存储数据。
  • B-tree索引适用于范围查询,例如大于、小于或介于某个值之间的查询。
  • B-tree索引可以按照索引字段的顺序存储数据,这使得它对于排序和范围查询非常高效。
  • B-tree索引对于插入、更新和删除操作的性能也相对较好。
  • B-tree索引可以用作唯一索引或非唯一索引。

哈希索引:

  • 哈希索引使用哈希函数将索引键映射到唯一的索引值。它将数据存储为哈希表的形式。
  • 哈希索引适用于等值查询,例如通过索引键直接查找某个值。
  • 哈希索引对于等值查询非常高效,查询的性能通常非常快。
  • 哈希索引不适用于范围查询,因为哈希函数无法保证索引键的顺序。
  • 哈希索引不支持部分索引列的查询,只能使用所有索引列进行查询。
  • 哈希索引不支持排序操作,因为数据存储在哈希表中,并没有按顺序排列。

优点和缺点:

  • B-tree索引的优点包括适用于范围查询、排序和插入、更新、删除操作的高性能。它能够满足更广泛的查询需求,是InnoDB默认的索引类型。
  • B-tree索引的缺点是对于等值查询的性能可能不如哈希索引。
  • 哈希索引的优点是对于等值查询非常高效,查询速度快。
  • 哈希索引的缺点是不支持范围查询、排序和部分索引列的查询,适用性相对较窄。

总的来说,选择使用B-tree索引还是哈希索引取决于具体的查询需求。如果你需要进行范围查询、排序或部分索引列的查询,那么B-tree索引是更好的选择。如果你主要进行等值查询,并且对查询性能有较高的要求,那么哈希索引可能更适合。

索引分类

MySQL 中的索引可以根据不同的特性和用途进行分类。下面是几种常见的索引类型:

  1. 单列索引(Single Column Index):
    单列索引是最基本的索引类型,它仅包含单个列。它可以加快根据该列进行查询、排序和过滤的速度。在创建单列索引时,可以选择普通索引(默认)或唯一索引。

    • 普通索引(Non-Unique Index):允许索引列中的值重复。
    • 唯一索引(Unique Index):要求索引列中的值是唯一的,不能重复。
  2. 复合索引(Composite Index):
    复合索引是包含多个列的索引。它可以根据多个列的组合进行查询、排序和过滤,提高多列条件下的查询性能。复合索引的创建顺序非常重要,因为要遵循最左匹配原则

  3. 主键索引(Primary Key Index):
    主键索引是一种特殊的唯一索引,用于唯一标识表中的每一行。一个表只能有一个主键索引,并且主键索引通常是自增长的整数列。主键索引对于快速查找和唯一性约束非常有效。

  4. 外键索引(Foreign Key Index):
    外键索引是用于建立表之间关联关系的索引。它通过引用其他表的主键索引,确保数据的完整性和一致性。外键索引可以加速关联查询,并提供了方便的约束功能。

  5. 全文索引(Full-Text Index):
    全文索引用于支持全文搜索,即对文本内容进行关键字搜索。它可以在大文本字段(如文章、评论等)上进行高效的全文搜索操作。

  6. 哈希索引(Hash Index):
    哈希索引使用哈希函数将索引列的值映射到哈希桶中,以提供快速的等值查询。然而,哈希索引只支持精确匹配查询,不支持范围查询或排序操作。此外,哈希索引对于索引列的数据分布要求较高。

  7. 空间索引(Spatial Index):
    空间索引用于对具有空间属性(如地理坐标、几何图形等)的数据进行高效的空间查询,如范围搜索、邻近搜索等。

这些是 MySQL 中常见的索引类型。在设计和选择索引时,需要根据具体的业务需求和查询模式来决定使用哪种类型的索引,以提高查询性能和数据的完整性。

索引创建

在 MySQL 中,可以使用以下方法创建索引:

  1. 创建表时指定索引:
    在创建表时,可以使用 CREATE TABLE 语句的 INDEXKEY 子句来指定索引。下面是一个示例:

    CREATE TABLE table_name (column1 datatype,column2 datatype,...INDEX index_name (column1, column2, ...)
    );
    

    在上述示例中,index_name 是索引的名称,column1, column2, ... 是要包含在索引中的列名。

  2. 使用 CREATE INDEX 语句创建索引:
    可以使用 CREATE INDEX 语句在已存在的表上创建索引。下面是一个示例:

    CREATE INDEX index_name ON table_name (column1, column2, ...);
    

    在上述示例中,index_name 是索引的名称,table_name 是要创建索引的表名,column1, column2, ... 是要包含在索引中的列名。

  3. 使用 ALTER TABLE 语句添加索引:
    可以使用 ALTER TABLE 语句在已存在的表上添加索引。下面是一个示例:

    ALTER TABLE table_name ADD INDEX index_name (column1, column2, ...);
    

    在上述示例中,table_name 是要添加索引的表名,index_name 是索引的名称,column1, column2, ... 是要包含在索引中的列名。

  4. 使用 CREATE UNIQUE INDEX 语句创建唯一索引:
    如果需要创建唯一索引,可以使用 CREATE UNIQUE INDEX 语句。唯一索引要求索引中的值是唯一的,不能重复。下面是一个示例:

    CREATE UNIQUE INDEX index_name ON table_name (column1, column2, ...);
    

    在上述示例中,index_name 是索引的名称,table_name 是要创建索引的表名,column1, column2, ... 是要包含在索引中的列名。

索引的最左匹配原则

索引的最左匹配原则是指,在使用复合索引(Composite Index)时,查询条件从左到右依次匹配索引的左侧列,并且只有在前面的列都匹配成功的情况下,才会继续匹配后面的列。

具体来说,如果有一个复合索引 (column1, column2, column3)则最左匹配原则要求查询条件中至少包含索引的最左侧列 column1,然后才能匹配第二列 column2,最后才能匹配第三列 column3

最左匹配原则的重要性在于索引的有效性。当查询条件中只涉及到索引的左侧列时,数据库可以直接使用索引进行快速定位和过滤,大大提高查询效率。而如果查询条件不满足最左匹配原则,索引的效果将会大打折扣,数据库可能需要遍历更多的数据行才能找到匹配的结果,导致查询性能下降。

以下是几个示例来说明最左匹配原则:

  1. 考虑一个复合索引 (column1, column2, column3),查询条件为 WHERE column1 = 'A'。根据最左匹配原则,只使用了索引的最左侧列 column1,这时索引可以被有效利用。

  2. 考虑同样的复合索引 (column1, column2, column3),查询条件为 WHERE column2 = 'B'。根据最左匹配原则,索引的最左侧列 column1 并未出现在查询条件中,因此索引将无法使用,查询性能可能较差。

  3. 考虑同样的复合索引 (column1, column2, column3),查询条件为 WHERE column1 = 'A' AND column2 = 'B'。根据最左匹配原则,查询条件包含了索引的最左侧两列,因此索引可以被充分利用。

注意如:

  • 复合索引 (column1, column2, column3),查询条件为 WHERE column2 = 'A' AND column1 = 'B'。查询条件和复合索引顺序不一样,用不到复合索引了。

  • 如果单一索引和复合索引都能进行搜索,这样mysql会选择单一索引,因为复合索引需要更多的存储空间。

如何查看索引

在 MySQL 中,可以使用以下方法来查看表的索引:

  1. 使用 SHOW INDEX 语句:
    可以使用 SHOW INDEX 语句来查看表的索引信息。下面是使用该语句的示例:

    SHOW INDEX FROM table_name;
    

    在上述示例中,table_name 是要查看索引的表名。执行该语句后,将返回表的索引信息,包括索引名称、关联的列、索引类型、唯一性等信息。

  2. 使用 SHOW CREATE TABLE 语句:
    可以使用 SHOW CREATE TABLE 语句来查看表的创建语句,其中包含了索引的定义。下面是使用该语句的示例:

    SHOW CREATE TABLE table_name;
    

    在上述示例中,table_name 是要查看索引的表名。执行该语句后,将返回包含表的创建语句的结果,其中包括了索引的定义信息。

  3. 使用 INFORMATION_SCHEMA 数据库:
    MySQL 提供了 INFORMATION_SCHEMA 数据库,其中包含了关于数据库、表、索引等的元数据信息。可以查询 INFORMATION_SCHEMA 数据库的相关表来获取索引信息。下面是一个示例查询:

    SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema = 'your_database' AND table_name = 'your_table';
    

    在上述示例中,将 your_database 替换为实际的数据库名,your_table 替换为实际的表名。执行该查询后,将返回与指定表相关的索引信息。

基数(Cardinality)

在MySQL中,基数(Cardinality)是指数据库表中某个列的唯一值的数量。它是衡量列的数据分布和选择性的指标。基数的高低可以影响查询性能和索引的效果。

基数的值越高,表示该列中的唯一值越多,数据分布更均匀,选择性更好。相反,基数较低表示该列中的唯一值较少,数据分布不均匀,选择性较差。

对于MySQL来说,基数是由存储引擎统计计算得出的,并保存在索引的统计信息中。存储引擎会根据实际数据和更新操作的频率来更新基数的值。

基数对于查询优化和索引的选择非常重要。当一个查询涉及到某个列时,优化器会利用基数信息来判断是否使用索引以及选择最优的执行计划。如果基数较低,使用索引可能并不高效,而全表扫描可能更合适。

在创建索引时,基数也是一个重要的考虑因素。如果某个列的基数非常高,那么该列的索引可能会非常有用,因为它可以帮助快速过滤掉大量的数据。相反,如果基数较低,索引的效果可能较差,因为它可能需要扫描更多的索引页来获取需要的数据。

可以通过使用SHOW INDEX命令或查询information_schema.statistics系统表来查看表中索引的基数信息。例如,使用以下命令查看表mytable的索引信息:

SHOW INDEX FROM mytable;

在输出结果中,可以看到每个索引的Cardinality列显示了索引的基数值。

需要注意的是,基数并不是唯一衡量索引性能的指标,其他因素如数据分布、查询模式等也会影响索引的选择和效果。因此,在设计和优化数据库时,综合考虑基数以及其他相关因素是很重要的。

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

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

相关文章

Ubuntu下安装、配置及重装CUDA教程

安装CUDA 前往Nvidia CUDA Tools官网选择对应的架构和版本下载CUDA 以如下架构和版本为例&#xff1a; 查看显卡驱动 nvidia-smi如果显卡驱动已经装了&#xff0c;那么在CUDA安装过程中不用再勾选安装driver 下载并安装CUDA wget https://developer.download.nvidia.co…

Spring AOP

目录 AOP 理解AOP AOP组成 AOP的优点 Spring AOP 使用Spring AOP 定义切面和切点 定义通知 动态代理 织入 AOP 理解AOP AOP即面向切面编程&#xff0c;简单来说&#xff0c;就是把一部分通用的功能集中的放在一个地方处理的思想。假如某一段代码很多地方要用到&…

创建型模式 - 建造者模式

概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于&#xff1a;某个对象的构建过程复杂的情况。 由于实现了构建和装配的解耦。…

pytest 参数化进阶

目录 前言&#xff1a; 语法 参数化误区 实践 简要回顾 前言&#xff1a; pytest是一个功能强大的Python测试框架&#xff0c;它提供了参数化功能&#xff0c;可以帮助简化测试用例的编写和管理。 语法 本文就赶紧聊一聊 pytest 的参数化是怎么玩的。 pytest.mark.par…

openGauss学习笔记-13 openGauss 简单数据管理-DELETE语句

文章目录 openGauss学习笔记-13 openGauss 简单数据管理-DELETE语句13.1 语法格式13.2 参数说明13.3 示例 openGauss学习笔记-13 openGauss 简单数据管理-DELETE语句 DELETE语句可以从指定的表里删除满足WHERE子句的行。如果WHERE子句不存在&#xff0c;将删除表中所有行&…

css 禁止多次点击导致的选中了目标div的文字

像下面这样的情况&#xff0c;就可以用这种方法避免掉 禁止多次点击&#xff0c;导致的&#xff0c;选中了目标div的文字 或者 禁止多次点击&#xff0c;导致&#xff0c;html结构被选中显示出来 .targetDiv {-webkit-user-select: none;-moz-user-select: none;-ms-user-sel…

【云原生】Docker的初步认识,安装与基本操作

一、Docker的相关知识 Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源。 Docker是在Linux容器里运行应用的开源工具&#xff0c;是一种轻量级的“虚拟机”。 Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的…

SpringCloud整合Sentinel

文章目录 1、Sentinel介绍2、安装Sentinel控制台3、微服务整合Sentinel 1、Sentinel介绍 阿里开源的流量控制组件官网&#xff1a;https://sentinelguard.io/zh-cn/index.html承接了阿里双十一大促流量的核心场景&#xff0c;如秒杀、消息削峰填谷、集群流量控制、实时熔断下游…

Python自动化之pytest常用插件

目录 1、失败重跑 pytest-rerunfailures 2、多重校验 pytest-assume 3、设定执行顺序 pytest-ordering 4、用例依赖&#xff08;pytest-dependency&#xff09; 5.分布式测试(pytest-xdist) 6.生成报告&#xff08;pytest-html&#xff09; 1、失败重跑 pytest-rerunfailu…

Flutter 小技巧之滑动控件即将“抛弃” shrinkWrap 属性

相信对于 Flutter 开发的大家来说&#xff0c; ListView 的 shrinkWrap 配置都不会陌生&#xff0c;如下图所示&#xff0c;每当遇到类似的 unbounded error 的时候&#xff0c;总会有第一反应就是给 ListView 加上 shrinkWrap: true 就可以解决问题&#xff0c;那为什么现在会…

椒图——靶场模拟

先查看ip&#xff0c;10.12.13.232模拟的外网ip&#xff0c;其他的模拟内网ip&#xff0c;服务里面搭建好的漏洞环境。 #第一个测试项目&#xff0c;web风险发现 新建&#xff0c;下发任务&#xff0c;点威胁检测&#xff0c;webshell&#xff0c;点扫描任务&#xff0c;点新…

QT中QTimer的循环时间与槽函数执行时间以及在事件循环中触发,不同时间的结果分析

目录 当循环时间小于槽函数时间时&#xff1a; 当循环间隔时间大于槽函数时间时&#xff1a; 当存在两个定时器器&#xff0c;其中一个还是间隔100ms&#xff0c;另一个间隔1000ms&#xff1a; 当两个定时器的循环周期大于槽函数执行时间时 当在主程序中添加一个for循环…

js - 对forEach()函数的一些理解

1&#xff0c;定义和用法 定义&#xff1a; forEach() 方法用于调用数组的每个元素&#xff0c;并将元素传递给回调函数。注意: forEach() 对于空数组是不会执行回调函数的。 用法&#xff1a; // 箭头函数 forEach((element) > { /* … */ }) forEach((element, index) &…

mcu 启动流程

MCU启动流程 MCU启动流程 MCU启动流程1 MCU的启动方式2 MCU程序启动执行过程3 启动过程的执行工作4 keil调式过程验证5 调试文件map 1 MCU的启动方式 单片机的启动方式&#xff0c;以stm32为例&#xff0c;如下&#xff1a; 不同的下载方式对应的不同的启动方式&#xff0c;st…

truffle 进行智能合约测试

本方法使用了可视化软件Ganache 前两步与不使用可视化工具的步骤是一样的&#xff08;有道云笔记&#xff09;&#xff0c;到第三步的时候需要注意&#xff1a; 在truffle插件下找到networks目录&#xff0c;提前打开Ganache软件 在Ganache中选择连接或者新建&#xff0c;我在…

如何学习Java集合框架? - 易智编译EaseEditing

要学习Java集合框架相关的技术和知识&#xff0c;可以按照以下步骤进行&#xff1a; 掌握Java基础知识&#xff1a; 在学习集合框架之前&#xff0c;确保你已经具备良好的Java编程基础&#xff0c;包括语法、面向对象编程&#xff08;OOP&#xff09;原理和常用的核心类库等。…

MySQL备份与还原/索引/视图

MySQL备份与还原/索引/视图练习 文章目录 一、备份与还原1、使用mysqldump命令备份数据库中的所有表2、备份booksDB数据库中的books表3、使用mysqldump备份booksDB和test数据库4、使用mysqldump备份服务器中的所有数据库5、使用mysql命令还原第二题导出的book表6、进入数据库使…

STM32案例学习 GY-39环境监测传感器模块

STM32案例学习 GY-39环境监测传感器模块 硬件平台 野火STM32F1系列开发板正点STM32F1系列开发板STM32F103ZET6核心板GY-39环境监测传感器模块 GY-39环境监测传感器模块 GY-39 是一款低成本&#xff0c;气压&#xff0c;温湿度&#xff0c;光强度传感器模块。工作电压 3-5v…

thinkphp 上传图片

public function upload_img(){// 读取图片资源// 存储路径$path "uploads/avatar";$file request()->file(background_img);// 存储图片$info $file->rule(uniqid)->move($path);// 存储成功if ($info) {//获取到上传图片的路径名称$name_img $path . …

linux查看ipynb文件

linux查看ipynb文件 使用jupyter查看 使用jupyter查看 安装 pip install jupyter添加配置好的环境到jupyter notebook的kernel中&#xff1a; python -m ipykernel install --user --name mmdet --display-name "mmdet"运行jupyter notebook &#xff08;在ipynb…