当前位置: 首页 > 后端技术 > Node.js

MySQL索引初探

时间:2023-04-03 10:42:10 Node.js

MySQL是项目开发中最常用的,但我对它的了解还是不多。开始学习索引,详细了解什么是索引,它们的作用是什么?为什么要建立索引?等一系列问题搞清楚。不能用的那么含糊。什么是索引?根据官方对索引的介绍,索引是一种帮助MySQL高效获取数据的结构。其实更通俗的说,MySQL索引就像一本书前面的目录,可以加快数据的查询速度。每个人以前应该都用过字典。字典前面有拼音查找和笔画查找。事实上,这种行为有点类似于MySQL的索引。一般来说,索引本身也很大,不可能全部存入内存。因此,索引往往保存在一个磁盘文件中,可能保存在单独的索引文件中,也可能与数据保存在同一个文件中,这种情况视情况而定。我们通常所说的索引包括聚集索引、覆盖索引、组合索引、前缀索引、唯一索引等,默认是使用B+树结构组织的索引(多路搜索树,不一定是二叉树).索引分类关于索引的种类,上面说的比较多,但是如何正确使用索引是个问题。下面一一说说常用的索引的种类。单列索引单列索引其实是一个统称。我是这样理解的。单列索引包括什么?单列索引包括普通索引、唯一索引和主键索引。单列索引是只包含单个列的索引,但一个表中可以有多个单列索引。普通索引是MySQL中的基本索引类型,没有任何限制,允许在定义索引的列中插入重复值和空值,纯粹是为了更快的数据查询。普通索引创建方法://方法一//在原表上增加普通索引ALTERTABLEusersADDINDEXindex_users(id)//方法二//在表中创建普通索引CREATEINDEXindex_nameONtable_name(column_name)uniqueindexindex列中的值必须是唯一的,但允许空值。主键索引创建方法://方法一//给原表添加唯一索引ALTERTABLEusersADDUNIQUE(id)//方法二//创建唯一索引,数据不能有重复值CREATEUNIQUEINDEXindex_usersONusers(id)主键索引这是一个特殊的唯一索引,不允许空值。一般在建表的时候指定了主键,就会创建一个主键索引(不能用CREATEINDEX创建主键索引,用ALTERTABLE代替)主键索引创建方法://添加列时原表,标记主键索引ALTERTABLEusersADDPRIMARYKEY(id)复合索引在表中多个字段的组合上创建索引,复合索引的使用需要遵循最左前缀原则。一般来说,建议使用复合索引,而不是单列索引。最左前缀原则就是最左优先级。检索数据时,从联合索引的最左边开始匹配。在使用该索引之前,组合索引的第一个字段必须出现在查询语句中。复合索引创建方法://创建复合索引ALTERTABLEarticleAddINDEXinde_time(title(50),time(10))单列索引(全文索引)全文索引只能在myisam引擎上使用,并且只能用在CHAR,VARCHAR,在TEXT类型的字段上使用全文索引,介绍一下需求,说说什么是全文索引,也就是在一堆文本中,通过某个关键字等,可以找到该字段所属的记录行。单列索引(全文索引)创建方法://创建全文索引CREATEFULLTEXTINDEXindex_nameONtable(column(length))altertabletable_nameaddfulltextindex_name(column)索引优缺点索引优点:可以提高数据检索效率,降低数据库IO成本,类似于书籍的目录,通过索引列对数据进行排序,降低了数据排序的成本和CPU消耗。索引的列会自动排序,包括单列索引和复合索引,但是复合索引的排序比较复杂。有的如果按照索引列的顺序排序,对应orderby语句,效率会提高很多。其中索引列在存储引擎层处理覆盖索引,不需要回表查询索引缺点:索引会占用内存空间,索引虽然会提高查询效率,但是会降低更新表的效率数据。比如每增加或删除一个表数据,MySQL不仅要保存数据,还要保存和更新相应的索引文件。索引原理上面已经讲过了。使用索引的目的是提高查询效率,降低IO的运行成本。其实原理和用字典差不多。通过不断缩小想要获取的数据范围,可以筛选出最终想要的数据结果,同时将随机事件变成顺序事件。也就是说,有了这种索引机制,你总能用同样的方法找到想要的数据。你想要的数据。其实回过头来看,数据库其实就是这样的,只是它内部的实现原理远比这复杂,因为在查询数据的时候,不仅仅是查询准确的值,有时我们可能还需要进行范围查询。实际上,索引本质上也会存储在磁盘上。这在上面已经提到了。实际上,索引的存储结构是在存储引擎中实现的。也就是说,会根据不同的存储引擎使用不同的索引。.myisam和innoDB的存储引擎只支持B+TREE,也就是说默认的BTREE不能被替换。InnoDB和Memory存储使用HASH和BTREE引擎,HASH索引一般比BTREE快。话虽如此,我将谈谈准时性。下面主要介绍B+TREE和BTREE的区别和工作原理。BTREE和B+TREE上面也提到了B+TREE是一个数据存储引擎。本质上,B+TREE在数据库中的实现是最常见的索引形式。接下来说说什么是BTREE和B+TREE。假设我们的数据结构如下图所示。看到图中不同的数字分为0012-0017,如果只看最底层,其实可以看到得到的是一个类似链表结构的数据结构图,通常称为叶子节点。其实BTREE和B+TREE最大的区别就是B+TREE只会生成叶子节点的所有数据,而BTREE会存储所有节点的数据。如果我们仔细观察叶子节点,就会发现内部数据结构是从右到左按照从小到大的顺序排列的。B+TREE中存储的数据是排成一行的,这些数据是用指针指向的,也就是顺序索引列,上图可以很清楚的看到。BTREE的高度一般在2到4之间,树的高度越高,直接影响到的IO速度就越高,因为每次IO都需要频繁的查找。如果三层结构支持的数据结构可以达到20G,那么四层树结构可以高达几十T。数据库表行与键值的逻辑(索引)顺序相同。一张表只能有一个聚簇索引,因为一张表的物理顺序只有一种情况,所以只能有一个对应的聚簇索引。如果索引不是聚集索引,则表中行的物理顺序与索引的顺序不匹配。与非聚集索引相比,聚集索引具有更快的检索速度。——摘自百度百科主键索引的叶子节点会存放数据行,也就是说数据和索引在一起,就是聚簇索引。二级索引将只存储主键值。如果没有主键,使用唯一索引恢复聚簇索引。如果没有唯一索引,Mysql会按照一定的规则创建聚集索引。主键索引InnoDB要求表必须有主键。如果没有显式指定主键,Mysql系统会自动选择一个能唯一表示数据记录的列作为主键。如果不存在这样的列,Mysql会自动为InnoDB表生成一个隐藏字段作为主键,其类型为longinteger。从上图可以清楚的看出数据块是直接挂在聚簇索引的主键下的,这也印证了上面说的内容。同时也证明了叶子节点下保存了当前数据块的完整数据。这种索引称为聚簇索引。因为InnoDB的数据文件本身就是按主键聚合的。这也证明InnoDB一定有主键。如果没有主键,数据就没有地方存放,因为所有的数据都挂载在叶子节点的主键下。上面说了,如果没有主键,Mysql会自动生成一个主键,但是不建议这样做。生成主键还是很有必要的,否则会给Mysql带来一些额外的任务。辅助索引叶子节点存放的是主键,所以这里又是一个新的知识点,敲黑板!哒~哒~哒~拿了蓝火的加特林失误重新开始。哒~哒~哒~这个地方要考试(面试),一定要注意哦。然后我们看数据结构图如下:如果我们的查询语句使用select*fromuserwhereage='19',那么我们在查询过程中会先找到age='19'下的id为11,但是这里的使用select*所以,找到对应的id后,会去主键数据树中查询需要的数据,然后这个过程被回调回表查询。说白了就是语句通过辅助索引找到主键,然后用主键找到对应的数据块后,就可以得到需要的数据了。在整个过程中,我想在获取数据之前两次检索所需的数据。太累了,标志查询太慢了。如果使用selectid,agefromuserwhereage='19',则SQL查询到的id和age字段现在存在于叶子节点中。因此,可以在辅助索引树上查询,根本不需要回表查询。您可以在辅助索引树上查询需要的数据。这种查询称为覆盖索引。其实我想要的我都能得到,不用去找别人要。非聚集索引(MyISAM)非聚集索引:非聚集索引是一种索引,其中索引的逻辑顺序不同于磁盘上行的物理存储顺序。——摘自百度百科其实说白了,数据和索引并不是存放在同一个文件中。它们分别是MYD和MYI。非聚集索引包含主键索引和存储指针值的二级索引。MYD和MYI是myisam引擎表的结构文件。从上面的结论可以得出myisam使用的是非聚集索引,太机智了,哈哈哈。PrimaryKeyIndex下图是数据结构图。如果我们数据表中的主键是id,图中使用的是myisam表的主索引。可见myisam的索引文件只是保存的数据地址。其实光看上图还是挺抽象的。非聚集索引的叶子节点仍然是索引节点,只是有一个指针指向对应的数据块。如果使用非聚集索引进行查询,查询的列中包含其他未覆盖列的索引,那么他需要进行二次查询,查询该节点上对应数据行的数据。需要知道的一件事是白色部分和彩色部分分别存储在两个不同的文件中。当我们通过主键查询时,我们通过主键存储的地址在数据表中找到对应的数据块。比如11对应的数据存储地址是0x1,那么数据表中对应的地址也一定是0x1,这样才能找到对应的对应数据块。辅助索引在MySAM中,主索引和二级索引在结构上没有区别,只是主索引要求key唯一,而二级索引的key可以重复。如果我们在age上创建一个辅助索引,这个索引的结构如下图所示。在辅助索引中,叶子节点也存储了对应数据块的地址,与主键索引一样,通过地址获取对应的块。索引使用场景上面已经介绍了索引的用法和简单的原理,那么我们在使用索引的时候应该如何正确的使用索引呢。需要创建索引:主键自动创建唯一索引。经常用作查询条件的字段应创建辅助索引。在关联查询中,关联字段应该创建一个索引。对于统计或者分组字段,应该建立索引`groupby不需要建立索引:表记录太少,频繁增删改表。where条件中经常更新的字段。首先对组合索引的最左边,即firstname字段的数据进行排序,按照第一个字段的排序,再对后面的第二个cid字段进行排序。其实相当于实现了orderbynamecid这样的规则。为了节省MySQL索引存储空间和提高搜索性能,可以创建复合索引。如果可以使用复合索引,就不要使用单列索引。为什么说复合索引节省空间呢?因为一个索引树上有3个索引,三个索引树分别对应一个索引,相比之下前者占用的资源更少。使用更多的复合索引更容易实现索引覆盖和提高查询性能。举个例子,a=1andb=2andc>3andd=4如果你按照(a,b,c,d)的顺序创建索引,d不会使用索引,如果你创建(a,b,d,c)可以使用索引,a,b,d的顺序可以任意调整。也就是说,复合索引从最左到最右进行匹配,直到遇到范围查询停止。如果没有范围查询,理论上里面的索引顺序是可以随意调整的。但实际中,将查询需求频繁或字段选择性高的列放在最前面,以提高索引的使用效率。综上所述,聚簇索引和非聚簇索引的查询区别我们已经讲了很多了。对于非聚集索引,它的内部存储就是地址。无论是主键索引还是辅助索引,都需要通过地址获取数据块。而聚簇索引在查询过程中取决于当前的查询情况,会根据不同的情况做相应的处理。主键索引查询数据是最快的。如果是辅助索引,尽量使用覆盖索引。如何使用覆盖指数更大的毛呢?那么就是使用多个复合索引来实现一个覆盖索引。在聚簇索引的情况下,如果是辅助索引,辅助索引树中的数据字段越多,回表查询的机会就越小。在使用索引的过程中,必须使用主索引和二级索引。最后,感谢您花这么长时间阅读这篇文章。如果文章中有什么问题,请在下方评论,我会第一时间进行更正。