为什么索引可以让查询变快?终于有人说清楚了!

面试官:为啥索引可以让查询变快? 毫无疑问,我们只能一页一页的翻,这是非人类能接受的工作,我们必然想的是先看目录,找到相关的字或者偏旁,然后去对应的地方查找文字,这样效率就大大提高了。这也解释了为什么索引应当尽可能的建立在主键这样的字段上,因为主键必须是唯一的,根据这样的字段生成的二叉查找树的效率无疑是最高的。计算机的存储设备有很多种,其中速度越快的越贵,因此容量也往往越小例如我们的RAM随机存储器,也就是大家平时说的内存条,速度慢的就相对便宜例如我们的硬盘。因此,如果要从硬盘访问数据,需要执行以下步骤,这也是性能开销的主要来源。 阅读详情

作者:Java架构领域
链接:https://www.jianshu.com/p/787b14655681

概述

人类存储信息的发展历程大致经历如下:

4dc93a9a657f7b3a892e4067868da02c.jpeg

由于是个人凭着自己理解总结的,因此可能不一定精确,但是毋庸置疑的是,在当代,各大公司机构部门的数据都是维护在数据库当中的。

数据库作为数据存储介质发展的最新产物,必然是具有许多优点的,其中一个很大的优点就是存储在数据库中的数据访问速度非常快。

数据库访问速度快的一个很重要的原因就在于索引index的作用。也就是这篇文章的主要想介绍的内容,为什么索引可以让数据库查询变快?

计算机存储原理

在理解索引这个概念之前,我们需要先了解一下计算机存储方面的基本知识。

我们知道数据持久化之后存在了数据库里,那么我现在的问题是数据库将数据存在了哪里?答案显然是存在了计算机的存储设备上。就个人电脑而言,数据被存在了我们的电脑存储设备上。

计算机的存储设备有很多种,其中速度越快的越贵,因此容量也往往越小例如我们的RAM随机存储器,也就是大家平时说的内存条,速度慢的就相对便宜例如我们的硬盘。而我们的数据往往都是被存在最慢的存储设备硬盘上的,因为存在当中的数据在断电之后依然存在。

计算机的存储介质有多种,例如硬盘,例如告诉缓存,不同的存储介质的数据读取速度是不一样的。例如,像RAM这样的易失性存储设备的读写操作就非常快,访问其中的数据几乎没有延迟性。

由于这个原因,计算机操作系统的设计是这样的:数据永远不会直接从硬盘等机械设备中取出,而是首先从硬盘转移到更快的存储设备,例如RAM,从RAM当中应用程序直接按需获取数据。

计算机内部的机械硬盘是下面这样的:

497ef8efcd9d8559134e8744286338e7.jpeg

在一个典型的硬盘驱动器中可以有很多个盘片,“盘片”在外观上非常类似于一个光盘(但具有很高的存储容量)。盘片又被磁道分条,同时一个盘片又可以分为扇区。

要获取数据,“盘片”需要由主轴进行旋转。大多数硬盘供应商都提到了主轴旋转的速度,例如,7200转/分和15000转/分。磁盘中的数据总是以扇区的固定大小倍数表示。因此,如果要从硬盘访问数据,需要执行以下步骤,这也是性能开销的主要来源。

确定数据所在的正确磁道,并将磁头移动到该磁道。即通常说的寻道。

让“主轴”旋转盘片,使正确的扇区位于“磁盘头”下方。

从扇区开始到扇区结束获取整个数据。

如果数据恰好分布在连续扇区上,那么它将提高获取数据的性能。因为主轴和磁头本身不需要移动/旋转,也就没有太多开销,但是大多数时候这种开销是存在的。

由于存在这种开销,我们不能直接从硬盘获取数据。RAM的存储器高性能的背后的主要原因是它没有像硬盘那样的机械运动部件。但是尽管RAM的性能很高,但它当中的数据却不会用作永久存储,断电之后就会消失,重新启动之后就什么都没有了,这是我们需要硬盘来进行持久化的原因所在。数据库中的数据毫无疑问就是存放在硬盘当中的,因此访问数据库中的数据不可避免的会经历磁盘操作的开销。

索引是如何工作的?

知道上述知识后,索引就更容易理解了。另外,MySQL 系列面试题和答案全部整理好了,微信搜索Java技术栈,在后台发送:面试,可以在线阅读。

举个例子,想象一下,现在有一本500页厚包含几十万字的字典,同时里面的字是无序排列的,现在我需要你从中找出某几个字出来同时不允许查看目录。毫无疑问,我们只能一页一页的翻,这是非人类能接受的工作,我们必然想的是先看目录,找到相关的字或者偏旁,然后去对应的地方查找文字,这样效率就大大提高了。目录事实上就是一种索引,其思想一脉相承。

数据库的索引类似于书中的这个目录。索引会帮助我们快速检索数据库,查询不需要通过整个表来获取数据,而是从索引中找到数据块。以一张数据库表为例:

f4ff5118872f292e08d4cc5a79e4109a.jpeg

上表是一张真实的数据库表,其中每一行是一条记录,每条记录都有字段。假设上面的数据库是一个有10万条记录的大数据库。现在,我们想从10万条记录中搜索一些内容,那么挨着一个一个搜索无疑将花费很长的时间,这个时候我们在数据结构与算法里学的二分查找法就派上了用场。

二分查找法

使用二分查找法,需要将数据先排序,但是其查询效率将大大提高。2021 最新 Java 面试题出炉!(带全部答案)关 注Java技术栈获取。

例子如下:

假设我们在上面的数据库中使用的是固定长度的记录,固定块记录大小为205个字节, 默认块大小是1024字节。则:

固定记录大小=204字节,块大小=1024字节

所以每个数据块的记录数=1024/204=5条记录,10万条记录就是2万个块

不使用任何算法,我们要查询100000条记录中的某一条,,在最坏的情况下我们需要遍历一遍2万block才能获得全部100000条记录。但如果进行二分查找,则只需要进行20000的对数基数2,即14.287712次即可。这意味着我们只需对排序后的值进行14次搜索,就可以使用二分查找到您感兴趣的唯一值。

c2b248062a42c01ef6109c966d1a2e79.jpeg

上图是对一串数字生成的二叉查找树。其时间复杂度为O(n)=O(log2N),即以2为底,n的对数。其中n为查找目标群体的总数据量。

例如,假设N为8,则O(n) = O(2为底8的对数) = O(3).

遍历方式,其时间复杂度为O(n)

在上述例子当中,n就是10000。使用索引的时间复杂度为O(2为底10000的对数) 大约等于 13. 和O(10000)之间差大概800倍。

索引为何使得查询变快?

这个时候我们就能直接回答上述问题了,建立了索引的数据,就是通过事先排好序,从而在查找时可以应用二分查找来提高查询效率。这也解释了为什么索引应当尽可能的建立在主键这样的字段上,因为主键必须是唯一的,根据这样的字段生成的二叉查找树的效率无疑是最高的。

为什么索引不能建立的太多?

如果一个表中所有字段的索引很大,也会导致性能下降。想象一下,如果一个索引和一个表一样长,那么它将再次成为一个需要检查的开销。这就好比字典的目录非常详细,但是其长度已经和所有的文字一样长,这个时候目录本身的效率就大大下降了。

索引有弊端吗?

肯定是有的,索引可以提高查询读取性能,而它将降低写入性能。当有索引时,如果更改一条记录,或者在数据库中插入一条新的记录,它将执行两个写入操作(一个操作是写入记录本身,另一个操作是将更新索引)。因此,在定义索引时,必须牢记以下几点:

索引表中的每个字段将降低写入性能。

建议使用表中的唯一值为字段编制索引。

在关系数据库中充当外键的字段必须建立索引,因为它们有助于跨多个表进行复杂查询。

索引还使用磁盘空间,因此在选择要索引的字段时要小心。

什么是聚集索引

聚集索引clustered index也叫聚簇索引,它的定义是:聚集索引的表中数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引。

例如:

26e6bd89a7f048c46392f5d8c33a8e1d.jpeg

结合上面的表格就很好理解了:数据行的物理顺序与列值的顺序相同,如果我们查询id比较靠后的数据,那么这行数据的地址在磁盘中的物理地址也会比较靠后。聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续。

为什么查询更快呢?我们通过上面的分析知道了索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。

主键一般会默认创建聚集索引。

在创建聚集索引之前,应先了解您的数据是如何被访问的。可考虑将聚集索引用于:微信搜索公众号:Linux技术迷,回复:linux 领取资料 。

包含大量非重复值的列。使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。被连续访问的列。返回大型结果集的查询。经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。OLTP型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。聚集索引不适用于:

频繁更改的列 这将导致整行移动,因为 SQL Server 必须按物理顺序保留行中的数据值。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的

索引失效的典型例子

条件中用or,即使其中有条件带索引,也不会使用索引查询,这就是查询尽量不要用or的原因,用in吧。

常见的sql优化手段有哪些

1.避免全表扫描

全表扫描往往发生在下面几种情况:

SQL的on子句或者where子句涉及到的列上没有索引;

表数据量很小,走索引查询比全表扫描更麻烦;这对于少于10行且行长度较短的表来说很常见

2.避免索引失效

不在索引列上做任何操作(计算,函数、自动or手动类型转换),这样会导致索引失效而转向全表扫描。

存储引擎不能使用索引中范围条件右边的列。这个是因为age中查询时范围查询了,pos列的索引就没有生效了。

尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *。

对于MySQL而言:

mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描

is null,is not null也无法使用索引

like 通配符开头'%abc..',mysql索引会失效会变成全表扫描的操作

3.避免排序,不能避免,尽量选择索引排序

4.避免查询不必要的字段

5.避免临时表的创建,删除

--完--



读到这里说明你喜欢本公众号的文章,欢迎 置顶(标星)本公众号 架构师指南,这样就可以第一时间获取推送了~


在本公众号 架构师指南,后台回复:架构师,领取2T学习资料 !
推荐阅读
1. 后端架构师技术大全(69个点)
2. 架构师如何设计权限系统?
3. 我怎么才能成为一个架构师 ?
4. 架构师从0搭建一套订单系统!
mysql使用索引为什么查询速度变快很多? 首先来看看表是否有索引的命令 show index from 表名; 看到主键索引,索引类型是BTREE(二叉树) 正是因为这个二叉树算法,让查询速度快很多,二叉树的原理,就是取最中间的一个数,然后把大于这个数的往右边排,小于这个数的就向左排,每次减半,然后依次类推,每次减半,形成一个树状结构图 例如上面的例子,我们不使用索引的话,需要查询11次才把编号为4的数据取出,如果 阅读详情

相关推荐

足球赛事数据API:开发者生存指南(附真实踩坑记录)

作为一个既爱看球又爱写代码的老宅男,我这些年用过的足球API比看过的比赛还多。从最初被各种API文档折磨到怀疑人生,到现在能闭着眼睛调接口,中间的血泪史够写本书了。今天就把这些经验(和教训)分享给各位同好,特别是那些正在为"老板要做个足球App"而秃头的同行们。文档清晰免费层可用响应格式规范API-Sports免费额度大方支持GraphQL有中文文档(难得!Sportmonks数据全面有Webhook支持按需付费。

Happy0970的博客 2196

高薪面试题:索引为什么会加快查询效率?深入理解MySQL索引原理和实现

说到索引,很多人都知道“索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址,在数据十分庞大的时候,索引可以大大加快查询的速度,这是因为使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据。但是索引是怎么实现的呢?因为索引并不是关系模型的组成部分,因此不同的DBMS有不同的实现,我们针对MySQL数据库的实现进行说明。

weixin_71690375的博客 1703

自定义css属性实现渐变边框动画

自定义cs属性实现渐变边框动画

lemon的博客 1875

为什么索引会加快查询速度?索引原理和使用原则

索引是什么? 索引图解 定义:数据库索引,是数据库管理系统(DBMS)中一个排序的数据结构,以协助快速查询、 更新数据库表中数据。 首先数据是以文件的形式存放在磁盘上面的,每一行数据都有它的磁盘地址。如果 没有索引的话,要从 500 万行数据里面检索一条数据,只能依次遍历这张表的全部数据, 直到找到这条数据。 但是有了索引之后,只需要在索引里面去检索这条数据就行了,因为它是一种特殊 的专门用来快速检索的数据结构,我们找到数据存放的磁盘地址以后,就可以拿到数据 了。就像我们从一本 500 页的书里面去找特定

weixin_43979902的博客 1万+

HackRF实战:用Portapack扩展板玩转GPS信号模拟(附固件刷写教程)

本文详细介绍了如何使用HackRF与Portapack扩展板进行GPS信号模拟,包括固件刷写、信号生成与发射配置等实战操作。通过专业工具和优化技巧,读者可以掌握软件无线电的高级应用,解决手机定位难题,同时强调安全合规使用的重要性。

weixin_28717431的博客 363

资金穿透分析

我们把准备好的银行数据导入到软件中,导入具体步骤这里不做详解,大家可以通过“清林情报分析师”公众号,查看操作视频第二节

清林情报分析师 3493

数据库添加索引为什么能加快查询速度

数据库建立索引为什么会加快查询速度 首先明白为什么索引会增加速度,DB在执行一条Sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。 MySQL官方对于索引的定义为:索引是帮助MySQL高效获取数据的数据结构。即可以理解为:索引是数...

蹲茅坑逗蛆蛆 4万+

【MicroPython编程-ESP32篇:设备驱动】-BNO08X系列传感器驱动

BNO08X 系列(BNO085/BNO086)是一款系统级封装 (SiP),集成了三轴加速度计、三轴陀螺仪、磁力计以及运行 CEVA SH-2 固件的 32 位 ARM® Cortex™-M0+ 微控制器。SH-2 包含 MotionEngine™ 软件,该软件提供复杂的信号处理算法来处理传感器数据,并提供精确的实时 3D 姿态、航向、校准加速度和校准角速度,以及更高级的上下文输出。BNO08X 集成在一个 28 引脚 LGA 封装中,尺寸为 3.8mm x 5.2mm x 1.1mm。它兼容 Andro

视觉与物联智能 696

为什么索引可以让查询变快?终于有人说清楚了

概述 人类存储信息的发展历程大致经历如下: 由于是个人凭着自己理解总结的,因此可能不一定精确,但是毋庸置疑的是,在当代,各大公司机构部门的数据都是维护在数据库当中的。 数据库作为数据存储介质发展的最新产物,必然是具有许多优点的,其中一个很大的优点就是存储在数据库中的数据访问速度非常快。 数据库访问速度快的一个很重要的原因就在于索引index的作用。也就是这篇文章的主要想介绍的内容,为什么索引可以让数据库查询变快? 计算机存储原理 在理解索引这个概念之前,我们需要先了解一下计算机存储方面的

superjava_的博客 2845

Vue - 详细实现低代码平台,支持拖曳式可视化生成应用软件功能,用户通过拖拽元素、搭积木的方式创建应用(适合迭代的基础架构、低代码平台)

Vue低代码平台-拖曳式拖拉拽可视化生成应用软件,拖拽式低代码数据可视化开发平台,vue实现拖拽,拖拽式Vue组件代码生成平台,基于vue的可视化拖拽代码生成工具,Vue实现可拖拽组件的方法,一个低代码平台的前端部分,靠拖拉拽生成页面。Vue技术栈从零实现低代码可视化搭建平台示例,低代码轮子,通过拖拽就可生成Vue代码的平台来了,vue低代码平台开发相关比低代码更强大的零代码开发平台,这款低代码SAAS数据可视化工具,拖拽生成大屏。vue实现拖拽效果,Vue自由拖拽缩放组件,自定义组件(文本、图片

🏆 前端领域优质创作者 1万+

分布式协作方案:OpenClaw多节点部署与设备互联

主从架构或对等架构服务发现与注册机制负载均衡策略选择分布式任务队列优先级调度失败重试机制WebSocket实时通信数据同步引擎冲突解决策略健康检查机制故障自动转移数据复制与恢复通过分布式部署,OpenClaw可以支撑更大规模的业务场景,提供更稳定可靠的AI助手服务。在下一篇文章中,我们将深入探讨安全与权限管理的精细化策略。

gaoxiang_120的专栏 371

为什么索引可以让查询变快

Table of Contents 概述 计算机存储原理 索引是如何工作的? 二分查找法 索引为何使得查询变快? 为什么索引不能建立的太多? 索引有弊端吗? 概述 人类存储信息的发展历程大致经历如下: 由于是个人凭着自己理解总结的,因此可能不一定精确,但是毋庸置疑的是,在当代,各大公司机构部门的数据都是维护在数据库当中的。数据库作为数据存储介质发展的最新产物,必然是具有许多...

topdeveloperr的博客 6520

OpenClaw 超级 AI 实战专栏【实战案例】(五)邮件收发 + 日历日程 + 文件管理一站式搞定

OpenClaw 实现办公自动化核心是模块解耦:邮件收发、文件管理、日历日程各自封装,便于维护和扩展;开发中需重点解决编码兼容、权限配置、时间格式、重复处理四大类坑点,核心思路是 “提前校验 + 异常兜底 + 统一格式”;敏感信息(邮箱密码、API Token)务必通过.env管理,避免硬编码泄露。

qq_36130719的博客 742

面试官:为啥加了索引查询会变快?

索引的原理,你清楚吗?

果子爸聊技术 2万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

为啥索引可以让查询变快

为啥索引可以让查询变快

【可全包】本人程序员,不需要做任何吹嘘,只是实在写点程序,写点文档,熟悉各类主流框架,SSM,SpringBoot,Flask,Djiango,Mysql,Sqlite,VUE,Uniapp等,各类程序设计专家,优质作者 1078

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

为什么索引可以让查询变快?终于有人说清楚了,nginx架构

确定数据所在的正确磁道,并将磁头移动到该磁道。即通常说的寻道。 让“主轴”旋转盘片,使正确的扇区位于“磁盘头”下方。 从扇区开始到扇区结束获取整个数据。 如果数据恰好分布在连续扇区上,那么它将提高获取数据的性能。因为主轴和磁头本身不需要移动/旋转,也就没有太多开销,但是大多数时候这种开销是存在的。 由于存在这种开销,我们不能直接从硬盘获取数据。RAM的存储器高性能的背后的主要原因是它没有像硬盘那样的机械运动部件。但是尽管RAM的性能很高,但它当中的数据却不会用作永久存储,断电之后就会消失,重..

m0_64867588的博客 669

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

讲讲为什么索引可以让查询变快

本文主要探讨数据库索引的工作原理及其对查询性能的提升。首先介绍了计算机存储介质的特点,指出硬盘数据访问存在机械操作开销。通过字典目录的类比,说明索引类似预先排序的目录结构,利用二分查找法将查询复杂度从O(n)降低到O(log₂n),极大提升查询效率。同时分析了索引的局限性:增加写入开销、占用存储空间,并解释了聚集索引的特性。最后列举了索引失效的常见场景和SQL优化建议,包括避免全表扫描、防止索引失效等。文章阐明了索引通过优化数据检索路径来加速查询的本质,同时提醒需要权衡索引带来的存储和写入性能代价。

【可全包】本人程序员,不需要做任何吹嘘,只是实在写点程序,写点文档,熟悉各类主流框架,SSM,SpringBoot,Flask,Djiango,Mysql,Sqlite,VUE,Uniapp等,各类程序设计专家,优质作者 883
上一篇: Notepad++又作死,国产文本编辑器Notepad--发布,支持Win/Linux/Mac平台
下一篇: 详解如何将 Android 手机投屏在 Ubuntu 上
编程IT圈
博客等级 码龄6年 1130粉丝 544原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值