Mysql高性能索引

一、索引是什么 

二、索引的底层实现原理

三、InnoDB的存储结构是怎样的? 

四、InnoDB索引和MyIsam索引对比 

 五、Mysql为什么会选错索引

六、唯一索引和普通索引的区别


导读:本博文讲解了索引是什么和索引的底层原理,提到了 BTREE和 B+TREE hash底层实现以及mysql选错索引的原因和解决方式。同时涵盖高频面试题之InnoDB索引和MyIsam索引对比区别,唯一索引和普通索引的区别。

一、索引是什么 

索引的概念:索引是一种特殊的文件,它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度

索引的作用:索引的目的在于提高查询效率,使原始的随机全表扫描变成快速顺序锁定数据

常用索引的分类:
普通索引:这是最基本的索引,它没有任何限制
唯一索引:引列的值必须唯一,但允许有空值(注意和主键不同)
组合索引:多个数据列组成的索引,遵守最左匹配原则

索引高性能保证:
    把查询过程中的随机事件变成顺序事件
    数据保存在磁盘上,而为了提高性能,每次又可以把部分数据读入内存来计算,访问磁盘的成本大概是访问内存的十万倍左右

磁盘IO与预读:
        考虑到磁盘IO是非常高昂的操作,计算机操作系统做了一些优化,当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内,因为局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。每一次IO读取的数据我们称之为一页(page)。具体一页有多大数据跟操作系统有关,一般为4k或8k

二、索引的底层实现原理

hash索引 无法满足范围查找,优点:等值检索快,范围检索很慢,因为hash值是不连续的

B-TREE 每个节点都是一个二元数组: [key, data],所有节点都可以存储数据。key为索引key,data为除key之外的数据

 B-TREE的缺点:插入删除新的数据记录会破坏B-Tree的性质,因此在插入删除时,需要对树进行一个分裂、合并、转移等操作以保持B-Tree性质。造成IO操作频繁。区间查找可能需要返回上层节点重复遍历,IO操作繁琐

B+Tree的改进:非叶子节点不存储data,只存储索引key;只有叶子节点才存储data

B+树高性能保证:

        3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高
在B+Tree的每个叶子节点增加一个指向相邻叶子节点的指针,就形成了带有顺序访问指针的B+Tree
B+TREE 只在叶子节点存储数据 & 所有叶子结点包含一个链指针 & 其他内层非叶子节点只存储索引数据。只利用索引快速定位数据索引范围,先定位索引再通过索引高效快速定位数据。

三、InnoDB的存储结构是怎样的? 

InnoDB物理存储结构分析

InnoDB以表空间Tablespace(idb文件)结构进行组织,每个Tablespace 包含多个Segment段,每个段(分为2种段:叶子节点Segment&非叶子节点Segment), 一个Segment段包含多个Extent,一个Extent占用1M空间包含64个Page(每个Page 16k),InnoDB B+Tree 一个逻辑节点就分配一个物理Page,一个节点一次IO操作。,一个Page里包含很多有序数据Row行数据,Row行数据中包含Filed属性数据等信息

 索引值匹配检索过程:确定定位条件, 找到根节点Page No, 根节点读到内存, 逐层向下查找, 读取叶子节点Page,通过 二分查找找到记录或未命中。(select * from user_info where id = 23) 

索引范围查找:读取根节点至内存, 确定索引定位条件id=18, 找到满足条件第一个叶节点, 顺序扫描所有结果, 直到终止条件满足id >=21 (select * from user_info where id >= 16 and id < 21)

 全表扫描:直接读取叶节点头结点, 顺序扫描, 返回符合条件记录, 到最终节点结束(select * from user_info where user_name = 'daniel')

四、InnoDB索引和MyIsam索引对比 

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址,MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复

InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引
第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域

MyIsam叶子data域放的是指针

InnoDB 主键索引,又是聚簇索引 (就是数据 和索引放在一起,我们称之为聚簇索引,性能最高)

 InnoDB非主键索引,非聚簇索引 data中存储的是id

InnoDB支持事务,MyISAM不支持
    InnoDB将多条SQL语言放在begin和commit之间,组成一个事务,具备事务的ACID
    InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败
    InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的
    InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快
    Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高

实际场景的选择
    是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;
    如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB
    系统奔溃后,MyISAM恢复起来更困难,能否接受;
    MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不会差 

 五、Mysql为什么会选错索引

场景举例分析 先造10万条数据入库:

CREATE TABLE `testwnn321` (`id` int(11) NOT NULL,`a` int(11) NOT NULL default 0,`b` int(11) NOT NULL default 0,PRIMARY KEY (`id`),KEY `a` (`a`),KEY `b` (`b`)
) ENGINE=InnoDB;
​
​delimiter ;;
create procedure wnndata321()
begindeclare i int;set i=1;while(i<=100000)doinsert into testwnn321 values(i, i, i);set i=i+1;end while;
end;;
delimiter ;
call wnndata321();explain select * from testwnn321 where (a between 1000 and 2000) and (b between 50000 and 100000) order by b limit 1;
​

 十万条数据入库后,我们先看看下面几个sql所使用的索引。

 原因分析:

在多个索引的情况下,优化器一般会通过比较扫描行数、是否需要临时表以及是否需要排序等,来作为选择索引的判断依据
选择索引 b,则需要在 b 索引上扫描 5w 条记录,然后同样回到主键索引上过滤掉不满足 a 条件的记录,因为索引有序,所以使用 b 索引不需要额外排序

解决方法:

使用force index a让mysql直接选择a索引来处理此处查询

其他场景导致索引选择错误:

数据表有频繁的删除或更新操作导致的数据空洞造成的
造成原因:分析器 explain 的结果预估的 rows 值跟实际情况差距比较大,分析器分析扫描行数用的是抽样调查
解决方案:统计信息不对,那就修正。analyze table test 命令,可以用来重新统计索引信息

六、唯一索引和普通索引的区别

 唯一索引:

定义:UNIQUE索引可以强制执行值唯一的一列或多列。一个表可以有多个UNIQUE索引。
场景:联系人的电子邮件唯一、联系人的身份证唯一 123@qq.com 数据库层面的严格唯一

查询上的区别:

对唯一索引,由于索引定义了唯一性,查找到第一个满足条件的记录后,就会停止检索
对普通索引,查找到满足条件的第一个记录’ab‘后,需查找下个记录,直到碰到第一个不满足k=’ab‘条件的记录
结论:mysql采用page页(一页16K)为数据单位从磁盘load出数据,除非刚好值为’ab‘的记录在一页的最后一条数据,否则执行性能区别微乎其微

修改上的区别:

对于唯一索引,所有更新操作要先判断该操作是否违反唯一性约束,唯一索引不会用change buffer
若所修改的数据在内存中
         找到索引对应该存储的位置,判断、到没有冲突,插入值,语句执行结束
         找到索引对应该存储的位置,插入值,语句执行结束。

若所修改的数据不在内存中
        需要将数据页读入内存,判断到没有冲突,插入值,语句执行结束
        将更新记录在change buffer,语句执行结束

change buffer的定义:
一种特殊的数据结构,该结构在 次要索引 中记录对 页 的更改
作用:提高更改索引操作性能,涉及更改缓冲区的一组功能统称为“更改缓冲区” ,由“插入缓冲区”,“删除缓冲区”和“清除缓冲区”组成
同步策略:当相关索引页被带入缓冲池而相关联的更改仍在更改缓冲区中时,该页的更改将使用更改缓冲区中的数据应用于缓冲池( 合并 )中。在系统大部分处于空闲状态或缓慢关机期间运行的“清除”操作会定期将新的索引页写入磁盘

结论:

唯一索引和普通索引在查询性能上没差别,主要考虑对更新性能影响
唯一索引可以从数据库上强制去重,但用不了change buffer的优化机制,从性能角度,推荐优先考虑非唯一索引

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

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

相关文章

MySQL:索引

一、索引的常见模型 索引的出现是为了提高数据查询的效率。实现索引的方式有很多种&#xff0c;比较常见的数据结构有&#xff1a;哈希表、有序数组和搜索树。 索引是在存储引擎层实现的&#xff0c;不同存储引擎索引工作方式不同。 1.1 哈希表 哈希表&#xff1a;键值存储…

【MySQL】MySQL的索引

目录 索引1.1 概念1.2 作用1.3 使用场景1.4 使用1.5 索引最常用的数据结构 索引 1.1 概念 索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引&#xff0c; 并指定索引的类型&#xff0c;各类索引有各自的数据结构实现。 …

MySQL 的索引

文章目录 索引简介普通索引主键索引唯一索引全文索引外键索引复合索引复合索引生效的几种方式复合索引会失效的情况 索引的优点高性能的索引策略独立的列前缀索引和索引的选择性复合索引选择合适的索引列顺序聚簇索引索引的 Btree 结构聚簇索引和非聚簇索引的区别聚簇索引的优点…

什么是 MySQL 索引?

什么是索引&#xff1f; 假设我们有一张数据表 employee(员工表)&#xff0c;该表有三个字段&#xff08;列&#xff09;,分别是name、age 和address。假设表employee有上万行数据(这公司还真大&#xff09;&#xff0c;现在需要从这个表中查找出所有名字是‘ZhangSan’的雇员信…

MySql知识体系总结(2021版)

存储引擎负责在MySQL中存储数据、提取数据、开启一个事务等等。存储引擎通过API与上层进行通信&#xff0c;这些API屏蔽了不同存储引擎之间的差异&#xff0c;使得这些差异对上层查询过程透明。存储引擎不会去解析SQL。 二、对比InnoDB与MyISAM 1、 存储结构 MyISAM&#xff…

一文搞懂MySQL索引所有知识点(建议收藏)

Mysql索引 索引介绍 索引是什么 官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说&#xff0c;数据库索引好比是一本书前面的目录&#xff0c;能加快数据库的查询速度。 一般来说索引本身也很大&#xff0c;不可能全部存储在内存中&#xff0c;因此索引往往是存储…

Doris安装

Apache Doris 由百度大数据部研发&#xff08;之前叫百度 Palo&#xff0c;2018 年贡献到 Apache 社区后&#xff0c; 更名为 Doris &#xff09;&#xff0c;在百度内部&#xff0c;有超过 200 个产品线在使用&#xff0c;部署机器超过 1000 台&#xff0c;单一 业务最大可达…

深入理解hashmap底层实现原理

目录 总体介绍 HashMap元素的存储 在hashmap中添加元素 HashMap的扩容机制 HashMap的线程安全性 1.添加和删除元素时存在不安全性 2.进行扩容操作时存在不安全性 3.哈希冲突存在不安全性 4.线程之间的不可见性导致安全问题 总体介绍 HashMap是我们用于元素映射使用频率最…

RK3588平台开发系列讲解(项目篇)YOLOv5部署测试

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、YOLOv5环境安装二、YOLOv5简单使用2.1、获取预训练权重文2.2、YOLOv5简单测试2.3、转换为rknn模型2.4、部署到 RK 板卡三、airockchip/yolov5简单测试3.1、转换成rknn模型并部署到板卡沉淀、分享、成长,让自己和他…

HTML编码问题导致的乱码

今天一个学弟问了一个问题&#xff0c;它写的HTML代码打开显示的是乱码。 然后就给我发来了代码。 就一个HTML文件和一个文件夹&#xff0c;打开一看&#xff0c;很简单的代码。 <!DOCTYPE html> <html lang""> <head><meta charset"UTF…

URL和HTML编码

URL和HTML编码 在呈现HTML页面时,有时候需要显示一些特殊的字符,例如”<”和”&”,因为它们是HTML专用字符,因此需要一些技巧.例如要想显示AT&T,在代码中必须写成AT&amp;T。同样URL中的,&,/等字符也为专用字符,所以如果需要在URL参数中使用它们,也必须对这些…

简单的Html编码转换工具

一、前言 因为项目经常会碰Html转码&#xff0c;特别是返回的xml报文&#xff0c;总是显示&# 十六进制的编码&#xff0c;查中文的时候特别不方便&#xff0c;所以就做了一个简单的C#桌面应用程序。 二、涉及软件 Visual Studio 2019 Preview 三、使用框架 .NET Fram…

怎么设置html代码中的编码格式,html怎么设置编码

在html中&#xff0c;可以使用meta标签来设置编码&#xff0c;语法格式“”。meta标签提供了HTML文档的元数据&#xff0c;元数据不会显示在客户端&#xff0c;但是会被浏览器解析&#xff1b;而charset属性用于定义文档的字符编码。 本教程操作环境&#xff1a;windows7系统、…

Unicode编码对应的HTML 、JS 、CSS码

平时写代码很少用到HTML的特殊字符&#xff0c;最常用的可能是 了&#xff0c;但有时在移动端为了节省时间&#xff0c;可能会用这些字符实现某种特殊效果&#xff0c;现整理如下&#xff1a; 使用方法&#xff1a; 这些字符属于unicode字符集&#xff0c;所以&#xff0c;你…

HTML之编码规范

HTML之编码规范 img 标签要写 alt 属性单标签不要写闭合标签自定义属性要以 data-开头td 要在 tr 里面&#xff0c;li 要在 ul/ol 里面ul/ol 的直接子元素只能是 lisection 里面要有标题标签使用 section 标签增强 SEO行内元素里面不可使用块级元素每个页面要写要用 table 布局…

【HTML 教程】HTML 字符编码

作者 | 阮一峰 简介 网页包含了大量的文字&#xff0c;浏览器必须知道这些文字的编码方法&#xff0c;才能把文字还原出来。 一般情况下&#xff0c;服务器向浏览器发送 HTML 网页文件时&#xff0c;会通过 HTTP 头信息&#xff0c;声明网页的编码方式。 Content-Type: text/ht…

HTML编码规范

本篇文章是基于王叨叨大佬师父维护的文档梳理的&#xff0c;有兴趣可以去看一下原文HTML编码规范。 1. 缩进与换行 【建议】 使用 2 个空格作为一个缩进层级&#xff0c;不允许使用tab字符 解释&#xff1a; ​ 具体项目&#xff0c;可以使用2个空格&#xff0c;也可以使用…

HTML 编码(字符集)总结,你了解了多少

Web 浏览器必须知道要使用哪个字符集&#xff0c;才能正确显示 HTML 页面。 文章目录 Web 浏览器必须知道要使用哪个字符集&#xff0c;才能正确显示 HTML 页面。前言一、HTML charset 属性二、字符集之间的差异ASCII 字符集ANSI 字符集 (Windows-1252)ISO-8859-1 字符集UTF-8 …

【HTML基础笔记】之【常用编码】

HTML 常用编码 4.1 HTML 实体编码 HTML实体编码&#xff0c;也即HTML中的转义字符。 在 HTML 中&#xff0c;某些字符是预留的&#xff0c;例如在 HTML 中不能使用小于号<和大于号>&#xff0c;这是因为浏览器会误认为它们是标签。如果希望正确地显示预留字符&#xf…

CTR预估之DNN系列模型:FNN/PNN/DeepCrossing

前言 在上一篇文章中 CTR预估之FMs系列模型:FM/FFM/FwFM/FEFM&#xff0c;介绍了FMs系列模型的发展过程&#xff0c;开启了CTR预估系列篇章的学习。FMs模型是由线性项和二阶交互特征组成&#xff0c;虽然有自动学习二阶特征组合的能力&#xff0c;一定程度上避免了人工组合特征…