普通索引和唯一索引详解

前言

面试的时候有时会问面试者,普通索引和唯一索引有什么区别。很多人,甚至工作很多年的工程师回答的千篇一律 “普通索引可以有重复的值,唯一索引不能有重复的值”。于是我又问,这两个索引这两个索引效率哪个高,很少有人回答的很好。下面我会从查询和更新多个维度去剖析这两个索引的区别。

现在我们系统有这样一个需求,根据用户的身份证查询用户的信息,用户表的数据很多。

select name from user where id_card='xxxx003'

为了查询的高效,我们肯定是要为id_card 建立索引,应该建立什么索引呢,有人说是主键索引,主键索引当然不合适,有下面几个原因:

  1. id_card 不能保证顺序递增,可能会导致页的分裂,

  2. 还有所占字节太大,主键索引每个叶存的数据太少,其他索引所占的空间也会增多,影响这个数据库的性能。

主键索引不合适,那么就剩下普通索引和唯一索引,对于这个需求,我们将逐步展开讨论。下面我将画出innodb 索引组织结构

接下来,我们就从这两种索引对查询语句和更新语句的性能影响来进行分析。

查询的区别

这个语句在B+tree 中查询过程是这样的,我们从id_card 索引树根开始查找,按层搜索到叶子节点,也就是找到了图中又下脚的那个数据叶。然后可以为数据页 内部通过二分法来定位记录。

  1. 那么对于普通索引来说,查找到 (xxxx003,3) 还需要往下找,直到找到下一个 id_card !='xxxx003' 停止

  2. 对于唯一索引来说,查找到 (xxxx003,3) 就停止,因为索引是唯一性的,查找到第一个满足条件的记录后,就会停止继续检索。

为此很多人感觉唯一索引在查询性能上高于普通索引,这个对性能的消耗微乎其微的。

大家都知道,在innodb 查询数据的时候,都是按数据页为单位读取的,也就是说,当我们查询一条数据,并不是这个记录本身从磁盘读出来,而是把这条数据所在页从磁盘中读出来,叶的默认大小是16kB,接下来的查询一般来说会在内存中遍历。为什么说一般来说呢,如果这条记录是页的最后一条,会经过磁盘对数据,稍微复杂点,这种概率很低,可以忽略。

更新的区别

Innodb 有个WAL机制,所谓的WAL机制就是先写日志,在刷盘。这样可以提高数据库的性能,否则只有每次读盘,特别是机械磁盘,一次读盘需要经过寻道,旋转,传输,性能会受到很大的影响。

对于日志来说不得不提到redo log 以及 change buffer,简单对比这两个机制在更新性能上的收益来说,redo log 主要节省的是随机写磁盘的 IO 消耗(转成顺序写),而 change buffer 主要节省的则是随机读磁盘的 IO 消耗。

change buffer 的WAL机制是怎么实现的?

当需要更新一个数据页的时候,如果数据页在内存中直接更新,没有在内存中,在不影响数据一致性的前提下,innodb 会将这个更新操作缓存到change buffer中,这样就不用从磁盘读取这个数据页了。下次查询这个数据页,在将数据页读到内存中,执行change buffer 与这个数据页有关的操作。这种方式就能保证这个数据逻辑的正确性。说明的是change buffer 不仅在内存中有,也会被写到磁盘中。

上面我们说到执行change buffer 与这个数据页有关的操作,就是我们所说的merge。以下情况也会出发merge,数据库正常关闭,后台线程会定时merge。

是不是很神奇,那么是不是只要对数据库的更新都能用到change buffer,其实不一定的。

现在举一个例子,我们要插入(5,xxxx005) 这条记录,我们要分情况讨论。

第一种情况,这个记录要更新的目标页在内存中。两种索引处理流程是这样的

  1. 唯一索引,会看 xxxx004 和 下一条记录之间是否存在一条 xxxx005的记录,没有才插入,语句执行结束。

  2. 普通索引,会在 xxxx004 和 下一条记录之间直接插入一条xxxx005的记录,语句执行结束。

这样看来,普通索引和唯一索引对更新语句性能影响的差别,只是一个判断,只会耗费微小的 CPU 时间。

第二种情况,这个记录要更新的目标页不在内存中

  1. 唯一索引,需要将数据页读入内存中,判断到没有冲突,插入这个值,语句执行结束

  2. 普通索引,只需要该记录在change buffer ,语句就执行结束了

将数据从磁盘读入内存涉及随机 IO 的访问,是数据库里面成本最高的操作之一。change buffer 因为减少了随机磁盘访问,所以对更新性能的提升是会很明显的。

唯一索引哪种情况下都无法使用change buffer,而普通索引可以通过使用change buffer通过减少磁盘的随机读而提高性能。在想想,如果数据在更新后,立马就读取。是不是每次都要触发change buffer 的merge ,不仅要随机读还要维护chage buffer。

那么普通索引和唯一索引该怎么选择了?

我们在业务开发时第一原则是保证业务的准确性,确实需要唯一索引保证数据的唯一性,我们用唯一索引。除此之外,普通索引的优点还是很多的,特别是有些业务写多,读少比如历史数据,特别是数据量很大的情况收益还是非常显著的。

change buffer 用的是 buffer pool 里的内存,因此不能无限增大。change buffer 的大小,可以通过参数 innodb_change_buffer_max_size 来动态设置。这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%。

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

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

相关文章

腾讯云优惠购买政策大全:新老用户都来瞧瞧!

腾讯云服务器多少钱一年?62元一年起,2核2G3M配置,腾讯云2核4G5M轻量应用服务器218元一年、756元3年,4核16G12M服务器32元1个月、312元一年,8核32G22M服务器115元1个月、345元3个月,腾讯云服务器网txyfwq.co…

script中的defer和async

在HTML中&#xff0c;<script>标签可以使用async和defer两个属性来控制外部JavaScript文件的加载和执行方式。这两个属性的目的是优化页面加载时间&#xff0c;但它们以不同的方式工作。下面是每个属性的具体说明&#xff1a; async属性 当你给<script>标签添加a…

pwa应用打开自动跳转到某个网页网址,并且全屏不显示网址url,就像这个网页也具备了pwa功能

问题描述 如果是只要在同一个域名下配置了pwa功能,那么当从桌面上打开这个pwa软件时,就会像真正的app运行一样,全屏显示,并且不显示网址的,但是如果要动态配置打开pwa时动态加载不同的网址,使用 window.location.href = “网址”这种形式重定向url就会导致pwa出现地址栏…

【MySQL】基本查询(表的增删改查)-- 详解

CRUD&#xff1a;Create&#xff08;创建&#xff09;&#xff0c;Retrieve&#xff08;读取&#xff09;&#xff0c;Update&#xff08;更新&#xff09;&#xff0c;Delete&#xff08;删除&#xff09;。 一、Create insert [into] table_name [(column [, column] ...)] v…

Unity中URP实现水体(水的焦散)

文章目录 前言一、原理1、 通过深度图&#xff0c;得到 对应像素 在 世界空间下的Z值2、得到模型顶点在 观察空间 下的坐标3、由以上两点得到 深度图像素 对应的 xyz 值4、最后&#xff0c;转化到 模型本地空间下&#xff0c;用其对焦散纹理采样 二、实现1、获取深度图2、在顶点…

警惕!2本期刊被剔除!2024年2月Scopus期刊目录已更新!

【SciencePub学术】 ​2024年2月&#xff0c;Scopus数据库迎来本年度第二次更新&#xff01;此次更新后&#xff0c;有94本期刊发生变动&#xff1a; • 剔除&#xff1a;有2本期刊不再被Scopus数据库收录&#xff08;Discontinued titles Jan. 2024&#xff09;&#xff1b; …

【低代码开发_RuoYi_框架】RuoYi框架_前端页面部署/搭建

开源软件的影响力 随着信息技术的快速发展&#xff0c;开源软件已经成为软件开发的趋势&#xff0c;并产生了深远的影响。开源软件的低成本、可协作性和透明度等特点&#xff0c;使得越来越多的企业和个人选择使用开源软件&#xff0c;促进了软件行业的繁荣。然而&#xff0c;…

在线原型工具有哪些比较好用?

随着云计算和5G网络的发展&#xff0c;互联网办公工具的发展 Web 这是一个不可避免的趋势。那么&#xff0c;对于产品设计团队来说&#xff0c;哪些在线设计工具值得体验呢&#xff1f;今天&#xff0c;让我们来看看一些国内外经典的在线原型工具。 即时设计 - 可实时协作的专…

比特币逼近历史高点,ETF疯了,Coinbase崩了,尼日利亚抓人了

2月28日&#xff0c;比特币冲高回落&#xff0c;加密货币交易所Coinbase则因宕机上演了一波“0元惊魂”。 比特币隔夜美股盘中突然飙高&#xff0c;突破6.4万美元大关&#xff0c;距历史新高仅一步之遥&#xff0c;但随后回落&#xff0c;几分钟之内就跌了5000美元&#xff0c…

2022年上半年教师资格证考试《综合素质》(中学)题

4.某校在初三年级实行两张课程表&#xff0c;一张公开的应对检查&#xff0c;一张不公开的实际执行&#xff0c;以提高升学率。对于该校做法&#xff0c;正确的是&#xff08;C &#xff09;。 A遵循了学科教学的基本规则 B降低了学生学习的效率 C漠视了学生全面发展的需要 …

vue3 + TS + vite 搭建中后台管理系统(开箱即用)

[TOC](vue3 TS vite 搭建中后台管理系统) 开箱即用 前言 要成功&#xff0c;先发疯&#xff0c;头脑简单往前冲&#xff01; 三金四银&#xff0c;金九银十&#xff0c;多学知识&#xff0c;也不能埋头苦干&#xff0c;要成功&#xff0c;先发疯&#xff0c;头脑简单往前冲…

linux系统---nginx(3)核心配置指令及调优

目录 Nginx 核心配置指令 一、Nginx配置文件详解 1、配置文件目录 2、配置文件结构 二、调优 1、在全局域进行的调优 1.1线程池指令 1.2 工作进程数指令 2.1 工作进程并非数指令 2.2 事件处理机制选择指令 2.3 互斥锁指令 3、在http指令域的调优 3.1 Nginx端口监听…

JAVA SE 2.基本语法

1.Java的基本语法 1.Java代码的基本格式修饰符 class 类名{程序代码 } 例: public class Test{public static void main(String[] args){} }语法说明 1.Java程序代码都必须放在类中&#xff0c;类需要用class关键字定义&#xff0c;class前面可以有修饰符2.当类不是定义在java.…

Redis学习------实战篇----2024/02/28

1.集群的session共享问题 2.基于Redis实现共享session登录 //4.保存验证码到redisstringRedisTemplate.opsForValue().set(LOGIN_CODE_KEYphone,code,LOGIN_CODE_TTL, TimeUnit.MINUTES);RedisTemplate RedisTemplate使用的是JdkSerializationRedisSerializer存入数据&#xff…

java面试题之nginx篇

1. 什么是Nginx&#xff1f; Nginx是一个 轻量级/高性能的反向代理Web服务器&#xff0c;他实现非常高效的反向代理、负载平衡&#xff0c;他可以处理2-3万并发连接数&#xff0c;官方监测能支持5万并发&#xff0c;现在中国使用nginx网站用户有很多&#xff0c;例如&#xff…

Linux NFC 子系统剖析

1.总览 linux源码中NFC在net/nfc下&#xff0c;文件结构如下图&#xff1a; hci&#xff1a;Host Controller Interface 主要是针对NFC的主机-控制器接口协议 nci&#xff1a;NFC Controller Interface 主要是NFC的控制器接口协议&#xff0c;用于NFCC(NFC Controller)和DH(…

微信小程序 uniapp+vue实习助学岗位系统springboot/php/python/nodejs

&#xff08;一&#xff09;研究目标&#xff1a; 对于本微信小程序实习系统的设计来讲&#xff0c;主要是采用了java语言和mysql数据库来完成对系统的设计&#xff0c;根据某高校的实习系统&#xff0c;提出解决问题的一个可行性方法&#xff0c;可以在手机端就能完成我们的工…

十三、Qt多线程与线程安全

一、多线程程序 QThread类提供了管理线程的方法&#xff1a;一个对象管理一个线程一般从QThread继承一个自定义类&#xff0c;重载run函数 1、实现程序 &#xff08;1&#xff09;创建项目&#xff0c;基于QDialog &#xff08;2&#xff09;添加类&#xff0c;修改基于QThr…

网络工程师笔记5

TCP/IP 常见协议 应用层 Telnet 数据网络中提供远程登录服务的标准协议23FTP 传输文件协议21&#xff0c;20HTTP 超文本传输协议80TFTPSNMPSMTPDNSDHCP 传输层 TCPUDP 网络层 ICMPIGMPIP 数据链路层 PPPOE Internet PPP 传输层 传输层协议接收…