数据库索引创建与优化 (3)

       从上面的执行计划可以看出,无论是是否使用索引,两次查询的耗时主要都在Sending Data上,这里Sending Data其实就是指MySQL服务器从磁盘上读取数据的耗时。对于上述查询,其实我们知道不使用索引的时候使用的是全表扫描,而使用索引的时候是索引过滤之后的数据扫描,并且由于MySQL的插件式存储引擎结构,其暂时是无法将where条件push down到存储引擎(如InnoDb)中进行数据扫描的,也就是说对于不使用索引的情况,MySQL是将数据从磁盘上读取到服务器层,然后依次扫描每条数据是否符合where条件,这也就是为什么不使用索引时其Sending Data如此之高的原因。对于使用索引的查询,从前面的二级索引结构图其实我们就已经知道,索引就是将字段数据去重分组之后的一个结构,并且叶节点上保存有所有相同数据的id,这样在使用first_name索引的时候,MySQL就可以过滤掉大部分数据,而直接从叶节点上获取符合条件的数据的id,这样从磁盘上读取的数据量将大大减少,这也就是为什么使用索引能够大幅提升效率的原因。

2.1.2 聚簇索引

       在索引结构一节我们讲了MySQL的聚簇索引的结构,也讲解了MySQL聚簇索引的生成方式,这里其实我们需要考虑的是两个问题:

如何使用聚簇索引提升查询效率;

如何自定义聚簇索引,及其优缺点;

       对于第一条,我们知道,聚簇索引最大的优点在于磁盘数据的存储顺序是按照聚簇索引的顺序组织的,并且由于磁盘驱动器在驱动磁头读取数据的时候,其是会顺序预读下一个数据页的数据的(比如磁头正在读取当前数据页的数据时其同时也会将紧邻的下一个数据页的数据读取到磁盘缓存中),那么如果我们查询的数据正好与磁盘数据的顺序一致时查询效率将得到大幅度提升。这里我们可以考虑一种情况,比如对于一个user表和一个message表,它们是一对多的关系,如果message表的数据能够按照其user_id字段聚簇,那么当查询一个user及其发送的消息时,查询效率将非常的高。另一种常见的聚簇索引用法就是在查询一系列的id数据的时候,MySQL会对这些id进行排序,这样更有利于顺序扫描数据,这也就是为什么我们使用in (id, id,…)的时候,无论in列表中顺序如何,最后得到的数据的顺序都是以id的顺序组织的(这一点感觉上像一个bug,但是理解了原因之后也情有可原)。

       根据前面的讲解,我们知道,如果需要表数据按照我们指定的方式组织,那么就只能对该表建立唯一索引,并且该表不能含有主键字段,如下图所示为一个自定义的聚簇索引表数据:

+-------+---------+-----------+-----------------+----------+--------------+-------------+ | id | site_id | config_id | exclude_site_id | excluded | show_in_site | show_in_crm | +-------+---------+-----------+-----------------+----------+--------------+-------------+ | 1 | -1 | 1 | 0 | 0 | 1 | 2 | | 2 | -1 | 2 | 0 | 0 | 1 | 2 | | 3 | -1 | 3 | 0 | 0 | 1 | 0 | | 4 | -1 | 4 | 0 | 0 | 1 | 0 | | 10 | -1 | 10 | 0 | 0 | 1 | 2 | | 11 | -1 | 11 | 0 | 0 | 1 | 2 | | 74601 | 60 | 1 | 0 | 0 | 1 | 2 | | 74546 | 60 | 2 | 0 | 0 | 1 | 2 | | 74592 | 60 | 21 | 0 | 0 | 1 | 3 | | 74534 | 60 | 65 | 0 | 0 | 1 | 2 | | 74513 | 79 | 71 | 0 | 1 | 1 | 1 | +-------+---------+-----------+-----------------+----------+--------------+-------------+

       上述数据建有唯一索引(site_id, config_id),并且id并不是主键,可以看到该表的数据并不是按照主键进行组织的,而是按照site_id和config_id的大小顺序依次组织的。

       关于第二个问题,上面其实已经进行了解答,这里我们需要着重说明一下自定义聚簇索引的缺点,如下图所示为一个聚簇索引业结构的示意图:

聚簇索引结构图

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyxxpj.html