人类存储信息的发展历程概览大致如下:由于是个人根据自己的理解总结出来的,不一定准确,但毫无疑问,在当代,主要的数据公司和部门都保存在数据库中。数据库作为数据存储介质发展的最新产物,必然具有很多优点,其中之一就是可以非常快速地访问存储在数据库中的数据。数据库访问速度快的一个很重要的原因就是索引索引的作用。那就是本文的主要内容,为什么索引可以让数据库查询更快?计算机存储原理在理解索引的概念之前,我们需要了解计算机存储的基础知识。我们知道数据持久化后是存储在数据库中的,那么我现在的问题是数据库把数据存储在哪里呢?答案显然存储在计算机的存储设备中。对于个人电脑,数据存储在我们的电脑存储设备上。计算机存储设备有很多种,其中速度越快的越贵,因此容量往往越小。比如我们的RAM随机存取存储器,也就是我们平时所说的记忆棒,速度慢的相对便宜,比如我们的硬盘。而我们的数据往往存储在最慢的存储设备的硬盘上,因为断电后现有的数据仍然存在。计算机的存储介质有很多种,比如硬盘,比如高速缓存,不同的存储介质读取数据的速度是不一样的。例如,对RAM等易失性存储设备的读写操作非常快,访问其中的数据几乎没有延迟。出于这个原因,计算机操作系统的设计方式是数据永远不会直接从机械设备(如硬盘)中获取,而是首先从硬盘移动到更快的存储设备(如RAM),应用程序从中获取数据根据需要直接转移。检索数据。电脑内部的机械硬盘是这样的:在一个典型的硬盘中,可以有很多盘片,“盘片”在外观上很像一张光盘(但存储容量大)。盘片由磁道条带化,一个盘片可以分成扇区。要获取数据,“盘片”需要由主轴旋转。大多数HDD供应商都会提到主轴旋转的速度,例如7200RPM和15000RPM。磁盘上的数据始终以固定大小的扇区倍数表示。因此,如果要从硬盘访问数据,需要执行以下步骤,这也是性能开销的主要来源。确定数据所在的正确轨道并将磁头移动到该轨道。这通常被称为寻求。让“主轴”旋转盘片,使正确的扇区位于“磁头”下方。获取从扇区开始到扇区结束的全部数据。如果数据恰好分布在连续的扇区上,那么它将提高获取数据的性能。由于spindle和head本身不需要移动/旋转,因此没有太多开销,但大多数时候这种开销是存在的。由于这种开销,我们无法直接从硬盘中获取数据。RAM的高性能背后的主要原因是它没有像硬盘那样的机械移动部件。但尽管RAM的性能很高,但其中的数据不会用于永久存储。断电后会消失,重启后就没有了。这就是为什么我们需要硬盘来持久化。数据库中的数据无疑是保存在硬盘中的,因此访问数据库中的数据必然会经历磁盘操作的开销。索引如何工作?了解了以上知识,索引就比较容易理解了。举个例子,假设有一本500页的字典,里面有几十万个单词,里面的单词是乱序排列的。现在我需要你从里面找出几个字,不允许你查看目录。毫无疑问,我们只能一页一页地翻页。这是人类无法接受的工作。一定要先看目录,找到相关的词或部首,然后到相应的地方去查文,这样效率会大大提高。增加。目录其实就是一种索引,其思想是一脉相承的。数据库的索引类似于书中的这个目录。索引将帮助我们快速检索数据库。查询不需要遍历整个表来获取数据,而是从索引中找到数据块。以数据库表为例:上表是一个真实的数据库表,每一行都是一条记录,每条记录都有字段。假设上面的数据库是一个有10万条记录的大型数据库。现在,如果我们要从10万条记录中查找一些内容,一条一条查找无疑需要很长时间。这时候,我们在数据结构和算法中学过的二分查找法就派上用场了。二分查找法使用二分查找法,需要先对数据进行排序,但其查询效率会大大提高。例子如下:假设我们在上面的数据库中使用定长记录,固定块记录大小为205字节,默认块大小为1024字节。那么:固定记录大小=204字节,块大小=1024字节,所以每个数据块的记录数=1024/204=5条记录,100000条记录是20000个块,不使用任何算法,我们需要查询100000条记录中的一条,在最坏的情况下,我们需要遍历20,000个区块才能获得所有100,000条记录。但是如果进行二分查找,只需要进行20000次以2为底的对数,即14.287712次。这意味着我们只需要对排序后的值进行14次搜索就可以使用二分查找找到你感兴趣的唯一值。上图是为一串数字生成的二叉搜索树。它的时间复杂度是O(n)=O(log2N),是n以2为底的对数。其中n是找到目标组的数据总量。例如,假设N为8,则O(n)=O(2是以8为底的对数)=O(3)。遍历方法的时间复杂度为O(n)。上例中n为10000,使用索引的时间复杂度为O(以10000为底的对数),约为13,O(10000)与O(10000)相差800倍左右。为什么索引使查询更快?这时候我们就可以直接回答上面的问题了。索引数据预先排序,可以应用二分查找来提高查询效率。这也解释了为什么索引要尽可能建立在像主键这样的字段上,因为主键必须是唯一的,而基于这样的字段生成的二叉搜索树的效率无疑是最高的。为什么索引不能建太多?如果一个表中所有字段的索引都很大,也会导致性能下降。想象一下,如果一个索引和一个表一样长,检查起来又会是一种开销。这就好比字典的目录很详细,但是它的长度却和所有的单词一样长。这时候目录本身的效率就大大降低了。索引有什么缺点吗?必须有,索引可以提高查询的读性能,反之则会降低写性能。当有索引时,如果你改变一条记录,或者在数据库中插入一条新记录,它会执行两次写操作(一次写入记录本身,另一次更新索引)。因此,在定义索引时,必须牢记以下几点:对表中的每个字段都建立索引会降低写入性能。建议对表中具有唯一值的字段进行索引。在关系数据库中充当外键的字段必须建立索引,因为它们有助于跨多个表进行复杂查询。索引也使用磁盘空间,所以在选择要索引的字段时要小心。什么是聚簇索引?聚集索引也称为聚簇索引。它的定义是:聚集索引的表中数据行的物理顺序与列值(通常是主键的列)的逻辑顺序相同。只有聚集索引。例如:结合上表,很容易理解:数据行的物理顺序与列值的顺序相同。如果我们查询id更晚的数据,那么这行数据的地址就会更接近磁盘中的物理地址。后退。聚集索引存储记录在物理上是连续的,而非聚集索引是逻辑上连续的,物理存储是不连续的。为什么查询更快?通过上面的分析,我们知道索引是用二叉树的数据结构来描述的。我们可以这样理解聚集索引:索引的叶子节点就是数据节点。非聚集索引的叶子节点仍然是索引节点,只是有一个指针指向对应的数据块。主键一般会默认创建聚簇索引。在创建聚簇索引之前,您应该了解您的数据是如何被访问的。考虑将聚簇索引用于:包含大量不同值的列。使用以下运算符返回值范围的查询:BETWEEN、>、>=、<和<=。按顺序访问的列。返回大型结果集的查询。使用连接或GROUPBY子句的查询经常访问的列;通常,这些是外键列。索引ORDERBY或GROUPBY子句中指定的列可以使SQLServer不必对数据进行排序,因为行已经排序。这提高了查询性能。需要非常快速的单行查找(通常通过主键)的OLTP样式应用程序。应该在主键上创建聚簇索引。聚簇索引不适合:频繁更改列这会导致整行移动,因为SQLServer必须按物理顺序保留行中的数据值。这一点要特别注意,因为在一个大数据量的事务处理系统中,数据是易变的,索引失??效的典型例子是usingorinthecondition。即使条件中有索引,也不会使用索引查询。这就是查询尽量不要使用or,使用in的原因。常见的SQL优化方法有哪些1.避免全表扫描全表扫描常发生在以下几种情况:SQL涉及的列上没有索引on子句或where子句;表数据量小,使用索引查询比全表扫描麻烦;常见于10行以下,行长较短的表2.避免索引失效不要对索引列做任何操作(计算、函数、自动或手动类型转换),这会导致索引失效和全表扫描。存储引擎不能使用索引中范围条件右侧的列。这是因为查询age的时候进行了范围查询,pos列的索引没有生效。尽量使用覆盖索引(只访问索引的查询(索引列与查询列一致)),减少select*。对于MySQL,mysql在使用不等(!=或<>)时无法使用索引,会导致全表扫描为null,不为null则无法使用索引。像'%abc..'开头的通配符,mysql索引就会失效会变成全表扫描操作3.避免排序,避免不了,尽量选择索引排序4.避免查询不必要的字段5.避免创建和删除临时表
