您当前的位置:首页 > 电脑百科 > 数据库 > 百科

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

时间:2022-12-09 11:56:01  来源:今日头条  作者:java小悠

概述

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


 

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

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

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

计算机存储原理

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

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

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

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

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

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


 

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

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

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

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

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

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

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

索引是如何工作的?

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

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

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


 

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

二分查找法

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

例子如下:

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

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

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

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


 

上图是对一串数字生成的二叉查找树。其时间复杂度为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也叫聚簇索引,它的定义是:聚集索引的表中数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引。

例如:


 

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

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

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

在创建聚集索引之前,应先了解您的数据是如何被访问的。可考虑将聚集索引用于:

包含大量非重复值的列。使用下列运算符返回一个范围值的查询: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.避免临时表的创建,删除

 

原文链接:https://mp.weixin.qq.com/s/t_VGq6omu75KYrCnJRTxcA


Tags:索引   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
搜索引擎大变局:向左AI,向右收费
自ChatGPT面世以来,它是否会取代谷歌的讨论就未曾止歇。近日,知情人士透露,谷歌正考虑对生成式人工智能驱动的新高级功能收费,这将是谷歌搜索业务史上最大的变革,传统搜索引擎公...【详细内容】
2024-04-09  Search: 索引  点击:(4)  评论:(0)  加入收藏
生成式人工智能在搜索引擎优化(SEO)中的应用顶级案例
原文作者 | Rahul Solanki生成式人工智能正在迅速改变搜索引擎优化 (SEO) 的工作方式。 这些新时代的语言模型和机器学习系统不仅可以研究大量信息,还可以理解上下文和含义,并...【详细内容】
2024-03-27  Search: 索引  点击:(10)  评论:(0)  加入收藏
Google搜索引擎索引的网页数量有多少?谷歌官方提供数据进行参考
Google搜索引擎索引的网页数量有多少?二十世纪九十年代,网页的索引数量成了一个各大搜索引擎相互对比的指标。小编记得2000年谷歌搜索引擎的首页搜索框上方,还标记着谷歌索引的...【详细内容】
2024-03-27  Search: 索引  点击:(16)  评论:(0)  加入收藏
MySQL:BUG导致DDL语句无谓的索引重建
对于5.7.23之前的版本在评估类似DDL操作的时候需要谨慎,可能评估为瞬间操作,但是实际上线的时候跑了很久,这个就容易导致超过维护窗口,甚至更大的故障。一、问题模拟使用5.7.22...【详细内容】
2024-03-26  Search: 索引  点击:(10)  评论:(0)  加入收藏
sem搜索引擎营销目标定位
当我们使用百度付费的竞价推广来做搜索引擎营销的时候,目标要定位好,这样才能把搜索营销的效果更大化,才能把七七鱼的竞价宗旨:花较少的钱得到更多的回报,发挥好。否则是花大钱也...【详细内容】
2024-03-25  Search: 索引  点击:(16)  评论:(0)  加入收藏
SEO优化全攻略:让你的网站在搜索引擎中脱颖而出
在这个数字化飞速发展的时代,拥有一个网站已不再是企业或个人的选择,而是必需品。然而,仅仅拥有一个网站并不足以吸引大量的流量和客户。为了让你的网站在众多竞争对手中脱颖而...【详细内容】
2024-03-25  Search: 索引  点击:(4)  评论:(0)  加入收藏
怎样知道域名有没有被搜索引擎惩罚过?
在网站推广的过程中,很多企业创建很多站点,我们会涉及到购买域名,那么如何判断域名是否被惩罚过?今天小编就跟大家来说说具体如何查询。1、网站收录如果你购买的域名可能是老域...【详细内容】
2024-03-21  Search: 索引  点击:(7)  评论:(0)  加入收藏
鲜为人知的搜索引擎优化(SEO)秘籍
随着互联网的普及和发展,搜索引擎优化(SEO)已经成为企业和个人在网络世界中争夺流量和曝光的重要手段。然而,很多从业者对于SEO的理解仍然停留在表面,实际上,有一些鲜为人知的SEO...【详细内容】
2024-03-12  Search: 索引  点击:(22)  评论:(0)  加入收藏
有什么办法能让新网站被百度等搜索引擎快速收录?,搜索引擎收录的原理
为了使新的网站能尽快被主流搜寻引擎如百度所收录,有几种行之有效的策略值得我们借鉴。这篇文章我将为大家提供九个切实可行的提示,以提升网站知名度,从而吸引更广泛的用户群体...【详细内容】
2024-03-12  Search: 索引  点击:(25)  评论:(0)  加入收藏
宝藏级Go语言开源项目——教你自己动手开发互联网搜索引擎
DIYSearchEngine 是一个能够高速采集海量互联网数据的开源搜索引擎,采用 Go 语言开发。Github 地址:https://github.com/johnlui/DIYSearchEngine运行方法首先,给自己准备一杯...【详细内容】
2024-03-12  Search: 索引  点击:(25)  评论:(0)  加入收藏
▌简易百科推荐
向量数据库落地实践
本文基于京东内部向量数据库vearch进行实践。Vearch 是对大规模深度学习向量进行高性能相似搜索的弹性分布式系统。详见: https://github.com/vearch/zh_docs/blob/v3.3.X/do...【详细内容】
2024-04-03  京东云开发者    Tags:向量数据库   点击:(5)  评论:(0)  加入收藏
原来 SQL 函数是可以内联的!
介绍在某些情况下,SQL 函数(即指定LANGUAGE SQL)会将其函数体内联到调用它的查询中,而不是直接调用。这可以带来显著的性能提升,因为函数体可以暴露给调用查询的规划器,从而规划器...【详细内容】
2024-04-03  红石PG  微信公众号  Tags:SQL 函数   点击:(5)  评论:(0)  加入收藏
如何正确选择NoSQL数据库
译者 | 陈峻审校 | 重楼Allied Market Research最近发布的一份报告指出,业界对于NoSQL数据库的需求正在持续上升。2022年,全球NoSQL市场的销售额已达73亿美元,预计到2032年将达...【详细内容】
2024-03-28    51CTO  Tags:NoSQL   点击:(14)  评论:(0)  加入收藏
为什么数据库连接池不采用 IO 多路复用?
这是一个非常好的问题。IO多路复用被视为是非常好的性能助力器。但是一般我们在使用DB时,还是经常性采用c3p0,tomcat connection pool等技术来与DB连接,哪怕整个程序已经变成以...【详细内容】
2024-03-27  dbaplus社群    Tags:数据库连接池   点击:(14)  评论:(0)  加入收藏
八个常见的数据可视化错误以及如何避免它们
在当今以数据驱动为主导的世界里,清晰且具有洞察力的数据可视化至关重要。然而,在创建数据可视化时很容易犯错误,这可能导致对数据的错误解读。本文将探讨一些常见的糟糕数据可...【详细内容】
2024-03-26  DeepHub IMBA  微信公众号  Tags:数据可视化   点击:(7)  评论:(0)  加入收藏
到底有没有必要分库分表,如何考量的
关于是否需要进行分库分表,可以根据以下考量因素来决定: 数据量和负载:如果数据量巨大且负载压力较大,单一库单一表可能无法满足性能需求,考虑分库分表。 数据增长:预估数据增长...【详细内容】
2024-03-20  码上遇见你  微信公众号  Tags:分库分表   点击:(16)  评论:(0)  加入收藏
在 SQL 中写了 in 和 not in,技术总监说要炒了我……
WHY?IN 和 NOT IN 是比较常用的关键字,为什么要尽量避免呢?1、效率低项目中遇到这么个情况:t1表 和 t2表 都是150w条数据,600M的样子,都不算大。但是这样一句查询 &darr;select *...【详细内容】
2024-03-18  dbaplus社群    Tags:SQL   点击:(6)  评论:(0)  加入收藏
应对慢SQL的致胜法宝:7大实例剖析+优化原则
大促备战,最大的隐患项之一就是慢SQL,对于服务平稳运行带来的破坏性最大,也是日常工作中经常带来整个应用抖动的最大隐患,在日常开发中如何避免出现慢SQL,出现了慢SQL应该按照什...【详细内容】
2024-03-14  京东云开发者    Tags:慢SQL   点击:(5)  评论:(0)  加入收藏
过去一年,我看到了数据库领域的十大发展趋势
作者 | 朱洁策划 | 李冬梅过去一年,行业信心跌至冰点2022 年中,红衫的一篇《适应与忍耐》的报告,对公司经营提出了预警,让各个公司保持现金流,重整团队,想办法增加盈利。这篇报告...【详细内容】
2024-03-12    InfoQ  Tags:数据库   点击:(32)  评论:(0)  加入收藏
SQL优化的七个方法,你会哪个?
一、插入数据优化 普通插入:在平时我们执行insert语句的时候,可能都是一条一条数据插入进去的,就像下面这样。INSERT INTO `department` VALUES(1, &#39;研发部(RD)&#39;, &#39...【详细内容】
2024-03-07  程序员恰恰  微信公众号  Tags:SQL优化   点击:(20)  评论:(0)  加入收藏
站内最新
站内热门
站内头条