MYSQL索引详解和优化

news2024/11/24 11:32:02

索引的定义

我们在看书的时候,都知道有目录,我们可以通过目录快速的找到书中的内容,而书中的目录就是充当书的索引。在数据库中的索引也是一样的。

索引的定义:

索引是帮助存储引擎快速获取数据的一种数据结构,即数据目录

索引的优缺点

索引的优点:

索引最大的优点就是提高查询速度

索引的缺点:

1.  要占据物理空间

2. 创建和维护索引都需要耗时,数据量越大越耗时

3. 会降低表的增删改效率,因为每次增删改都会动态维护索引

所以索引的使用也要根据具体情况而定,一般只会在这些这段下建立索引:有唯一性限制的字段,经常在where语句出现的字段,经常在GROUP BY 和 ORDER BY 出现的字段。

而不建议建立索引的字段:

1. 不经常在where语句,GROUP BY 和 ORDER BY 语句的字段,不建索引

2. 大量重复数据的字段,不建索引

3. 表数据太少,不建索引

4. 经常更新的字段,不建索引

索引分类

数据结构分类

在MYSQL中,从数据结构进行索引分类:

B+tree索引:把所有的数据都存储在叶子结点上面,非叶子结点只存储索引,这样可以保证最少次数的IO提高索引查询的性能

Hash索引:就是根据给定的字段,进行创建Hash值。可以很快的进行单个匹配度查询,但是无法做到范围查询

Full-text索引:一个比较特殊的索引,一般用的也很少。它查找的是文本中的关键词,而不是比较索引中的值。全文索引更类似于搜索引擎做的事

但是每种存储引擎所支持的索引是不相同的,下面我们对MYSQL中的 常见存储引擎 Innodb和MyISAM进行对比:

 从对比中我们知道每一种存储引擎支持的索引类型不一定相同。而下面我们重点讲的是Innodb存储引擎中B+Tree 索引类型,也是MYSQL5.5之后的默认存储引擎。

B+Tree 索引

在创建表的时候,Innodb存储引擎会根据具体场景设计索引:

1.  有主键,那么主键做聚簇索引的key

2.  没有主键,就选择第一个不包含 NULL 值的唯一列作为聚簇索引的key

3.  以上都不符合,那就主动生成一个隐式自增 id 列作为聚簇索引的key

除了聚簇索引,其他索引都属于辅助索引,也被称为二级索引或非聚簇索引。创建的主键索引和二级索引默认使用的是 B+Tree 索引

那么 B+Tree 索引在存储是什么样子的呢?

B+Tree 是一种多叉树,叶子点才存放数据,非叶子点只存放索引,而且每个节点里的数据是按主键顺序存放的。每一层父节点的索引值都会出现在下层子节点的索引值中,因此在叶子节点中,包括了所有的索引值信息,并且每一个叶子节点都指向下一个叶子节点,形成一个链表。如下图:

主键索引 B+ Tree

 假如我们要查找主键值为30的数据,查找过程如下:

1.  将 30 与根节点的索引数据 (15,56,77) 比较,30 在 15 和 56 之间,所以根据 B+Tree的搜索逻辑,找到第二层的索引数据 (15,20,49);

2. 在第二层的索引数据  (15,20,49)中进行查找,因为 30 在 20 和 49 之间,所以找到第三层的索引数据(20, 30);

3. 在叶子节点的索引数据(20, 30)中进行查找,然后我们找到了主键值为 30 的行数据。

从例子中我们知道,我们总共走了3个节点找到数据,其实也就是说我们进行了3次I/O操作。因为所有数据(索引和数据)都是存在磁盘里的,我们没读取一个节点就会就行一次I/O操作。

而且B+Tree存储千万级别的数据也就3-4层就可以满足,也就是说查询千万级别的数据也就进行了3,4次I/O操作。所以B+Tree 相比于 B 树和二叉树来说,最大的优势在于查询效率很高,因为即使在数据量很大的情况,查询一个数据的磁盘 I/O 依然维持在 3-4次。

如果是二级索引(非聚簇索引),那是不是跟主键索引(聚簇索引)一样呢?

肯定是不一样的。它们的区别如下:

1. 聚簇索引的 B+Tree  的叶子节点存放的是实际的数据记录,而且实际的数据记录只会存在这里。

2. 非聚簇索引的 B+Tree  的叶子节点存放是主键值和索引值,没有实际数据记录。

所以说,如果要通过非聚簇索引找到一条完整的实际数据记录,那么它得也通过非聚簇索引找到叶子节点,然后获取主键值,再根据这个主键值在主键索引的B+Tree中找到对应的叶子节点,拿到完整的实际数据记录。而这个过程就是做回表,也就是进行了两次B+Tree搜索找到数据。如果我们通过非聚簇索引一次搜索就得到想要的数据结果,那么久叫做覆盖索引。下面说明非聚簇索引的过程,如下:

二级索引 B+Tree

回表

上面有两个问题:

B+Tree的3-4层高能存储千万级别的数据,怎么计算的?

详细了解的这个问题可以看这篇:

为什么 MySQL InnoDB  选择 B+tree 作为索引的数据结构?

详细了解的这个问题可以看这篇:

物理存储分类

在MYSQL中,从物理存储进行索引分类:

主键索引(聚簇索引)

二级索引(非聚簇索引/辅助索引)

这两个区别在上面有说过,区别在于叶子节点存储的数据。

字段特性分类

在MYSQL中,从字段特性进行索引分类:

主键索引

唯一索引

普通索引

前缀索引

主键索引

主键索引就是建立在主键上的索引,通常在创建表格的时候一起创建,一张表只能有一个主键,而且不能为空。

创建方法:

CREATE TABLE table_name  (

      ....

    PRIMARY KEY (index_column_1)

);

唯一索引

唯一索引就是建立在 UNIQUE 字段上的索引,一张表可以有多个唯一索引,但索引列的值必须唯一,但是允许有空值。

创建方法:

方法一:

CREATE TABLE table_name  (
  ....
  UNIQUE KEY(index_column_1,index_column_2,...) 
);

方法二:

CREATE UNIQUE INDEX index_name ON table_name(index_column_1,index_column_2,...);

普通索引

普通索引就是建立在 普通字段上的索引。

创建方法:

方法一:

CREATE TABLE table_name  (
  ....
  INDEX(index_column_1,index_column_2,...) 
);

方法二:

CREATE INDEX index_name ON table_name(index_column_1,index_column_2,...);

前缀索引

前缀索引是指对字符类型字段的前几个字符建立的索引,而不是在整个字段上建立的索引,前缀索引可以建立在字段类型为 char、 varchar、binary、varbinary 的列上。使用前缀索引的目的是为了减少索引占用的存储空间,提升查询效率.

创建方法:

方法一:

CREATE TABLE table_name  (
 column_list,
  INDEX(column_name(length))
);

方法二:

CREATE INDEX index_name ON table_name(column_name(length));

字段个数分类

在MYSQL中,从字段个数进行索引分类:

单列索引

联合索引(复合索引)

单列索引

建立在单列上的索引称为单列索引, 比如主键索引

联合索引

联合索引就是将多个字段组合成一个索引。联合索引的遵循的规则:

最左匹配原则,即按照最左优先的方式进行索引的匹配。所以建立联合索引时的字段顺序,对索引效率也有很大影响。越靠前的字段被用于索引过滤的概率越高,实际开发工作中建立联合索引时,要把区分度大的字段排在前面,这样区分度大的字段越有可能被更多的 SQL 使用到。区分度就是某个字段 column 不同值的个数「除以」表的总行数,即区分度 = distinct(columnn)/ count(*)

例如,我们有个(a,b,c)联合索引,符合联合索引的:

where a = 2;

where a = 2, b = 2;

where a = 2, b = 2, c = 2;

不符合联合索引的:

where b = 2;

where c = 2;

where b = 2, c = 2;

不符合联合索引是因为不符合最左匹配原则。

索引操作

创建索引请查看上面具体索引部分

查看索引:

SHOW INDEX FROM table_name;

删除索引:

DROP INDEX index_name ON table_name;

ALTER TABLE table_name DROP INDEX index_name;

索引优化方法

MySQL数据库优化总结中的 索引优化

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

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

相关文章

flex设置为1后为什么要设置width为0,和布局超出省略号为什么会超出容器,为什么会没有用

前言 最近在做手机端的页面,制作过程出现了flex布局的一些问题,再次记录在解决办法关于在flex:1的情况下设置为width的效果 如果没有设置width,当内部元素的内容大小超过平均分配的剩余空间时,元素的宽度等于内容大小,如果设置了width并且这个width的大小小于平均分配的剩余空…

[Linux] 如何查看内核 Kernel 版本(查多个Kernel的方法)

上图来源于:turnoff.us,描述了Linux内核结构,有兴趣的同学可以访问原址看看 文章目录什么是Linux内核查看Linux内核Kernel的场景情况查看 Kernel 的几种方式1、使用 uname2、使用 hostnamectl 命令3、查看 /proc/version4、使用 rpm 命令5、使…

2.9 场景式文案,原来是这样子写的【玩赚小红书】

人的生活,就是一个场景连着另一个场景,循环往复,朝朝暮暮。 文案,只要切入了用户的场景,就可以切入他的生活,进而切入他的心。 什么是「 场景化文案」 ?可以看一组对比: 非场景文…

Tomcat的概述、部署、优化

文章目录一、Tomcat概述1、Tomcat的概念2、Tomcat的核心组件3、Java Servlet 的概念4、JSP的概念5、Tomcat顶层架构6、Container 结构分析:7、Tomcat请求过程二、Tomcat服务部署1、Tomcat服务部署的步骤1.1 关闭防火墙,将安装 Tomcat 所需软件包传到/opt目录下1.2 安…

C语言第十课(上):编写井字棋游戏(综合练习1)

目录 前言: 一、文件建立: 1.头文件game.h: 2.函数定义文件game.c: 3.工程测试文件test.c: 二、编写井字棋游戏: 1.程序整体执行思路: 2.menu菜单函数实现: 3.game游戏函数逻辑&am…

Linux环境下基于VSCode和CMake实现C/C++开发

layout: post title: Linux环境下基于VSCode和CMake实现C/C开发 description: Linux环境下基于VSCode和CMake实现C/C开发 tag: 开发工具 文章目录Linux开发环境Linux目录结构常用指令选项ls:list directory contentscd:change directorytouch&#xff1a…

【附源码】计算机毕业设计JAVA校园讲座管理

【附源码】计算机毕业设计JAVA校园讲座管理 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JAVA mybati…

linux驱动之mmap地址映射

应用场景 首先在linux中应用程序无法是直接访问驱动程序的数据的, 需要通过 copy_to_user 和 copy_from_user才能实现数据传输, 那么数据量大了以后如LCD的数据, 那么就会有很长的耗时, 为了解决这一问题, 引入mmap, 将底层物理地址映射出来, 让应用程序得以直接读写这一块内存…

Linux进程控制(下)--->进程程序替换

文章目录什么是进程程序替换为什么要进行进程程序替换怎么进行进程程序替换execlexecvexeclpexecvpexecleexecvpe使用c的可执行程序调用一个python脚本如何理解进程程序替换进程程序替换接口的返回值从进程独立性体会程序替换什么是进程程序替换 在讲进程程序替换之前&#xf…

[附源码]java毕业设计兰州市邮政公司新邮预订户管理信息系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

计算机毕业设计springboot+vue+elementUI在线漫画周边销售购物交流系统

项目介绍 任何系统都要遵循系统设计的基本流程,本系统也不例外,同样需要经过市场进行调研,漫画需求进行分析,概要设计,系统详细设计,测试和编码等步骤,设计并实现了“漫画之家”系统 。系统选用…

web前端设计与开发期末作品_期末大作业-疫情

Web前端开发技术 描述 网页设计题材,DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业,击疫情致敬逆行者感人类题材 | 致敬逆行者网页设计作品 | 大学生抗疫感动专题网页设计作业模板 | 等网站的设计与制作 | HTML期末大学生网页设计作业 HTML&#xff1a…

大一学生Web课程设计 红酒美食主题网页制作(HTML+CSS+JavaScript)

Web前端开发技术 描述 网页设计题材,DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 茶文化网站 | 中华传统文化题材 | 京剧文化水墨风书画 | 中国民间年画文化艺术网站 | HTML期末大学生网页设计作业 HTML:结构 CSS:样式 在操作方面上运…

通用后台管理系统前端界面Ⅵ——首页、登录页、404页面

登录页 1、为了方便起见,先将element-ui的使用改为全局引入的方式。修改main.js文件如下: import Vue from vue import App from ./App.vue import ElementUI from element-ui import element-ui/lib/theme-chalk/index.css //这个是局部引入&#xff0…

idea创建javaweb项目步骤超详细(2022最新版本)

目录 前言: 一、新建文件 1.在idea里面点击文件-新建-项目 2.新建项目-更改名称为自己想要的项目名称-创建 3.右键自己建立的项目-添加框架支持 4.勾选Web应用程序-确定 5.建立成功界面 二、配置tomcat 6.点击添加配置文件 7.点击这个 8.选择这个tomcat的本…

数据分析利器:XGBoost算法最佳解析

XGBoost是一种经典的集成式提升算法框架,具有训练效率高、预测效果好、可控参数多、使用方便等特性,是大数据分析领域的一柄利器。在实际业务中,XGBoost经常被运用于用户行为预判、用户标签预测、用户信用评分等项目中。XGBoost算法框架涉及到…

javaWeb项目基于tomcat运行部署后访问方案总结

javaWeb项目基于tomcat运行部署后访问方案总结 1.需求背景 最近接到一个老项目,这个是一个前后没有分离的java+jsp项目,所以前后端的代码是在一个项目里面的,因此在这个项目上开发就需要面临第一个问题:启动运行项目。简介:Java Web,是用Java技术来解决相关web互联网领域…

字符串的算法题目-字符串

题目一: 描述 对于一个长度为 n 字符串,我们需要对它做一些变形。 首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写…

【Java】数组中值得说的那些事

文章目录前言一、数组的创建及初始化🌳1、数组的创建🌳2、数组的初始化🍑(1)动态初始化🍑(2)静态初始化二、数组的使用🌳1、数组中元素访问🌳2、遍历数组&…

力扣LeatCode算法题-两数之和(二)

力扣算法题第二题,两数相加算法题: 要求: //给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 //如果,我们将这两个数…