Explain输出详解(下)

1.2.3 table

该字段表明当前查询正在访问哪张表。该表名可能是真实的表,也可能是查询过程中产生的临时表。如执行explain select id from user_info union select user_id from order_info,输出信息如下。

其中第三个查询的 table字段值为 <union 1,2>,就是查询过程中产生的临时表。

1.2.4 partitions

该字段的值表明分区表使用哪个分区。因为我们创建的表都是非分区表,故该字段的值为NULL。这里有一个新的概念——分区表,下面我将对分区表进行讲解。

我们知道在Mysql中一张表有一个数据文件存放表中的记录,当表中的数据量太大的时候,那么数据文件就很变得很大。这时,对表中记录进行增删改查操作的时间就会很大,特别的,如果需要定期删除过时的数据,耗时也会很大。因此,Mysql提供了分区的功能,在物理上将一张大表按照分割逻辑分成多张小表,此时,原来的超大数据文件就分割成了多个较小的数据文件。当我们去查找一条数据时,不再像以前一样到大的数据文件中查找,而是只要知道这条数据在哪张子表中,然后就到该子表的数据文件中查找。如果表的数据太大,可能一个磁盘放不下,这个时候,我们可以把数据分配到不同的磁盘里面去。

通俗地讲表分区就是按照分割条件将一张大表分割成独立的多个小表,每个小表之间独立存储和管理。查询的时候,先根据分割条件判断出数据可能在哪些小表上,然后在这些小表中分别独立查询出数据返回给用户,其中在小表中查询数据和在普通的表上查询数据的过程一模一样。

前面多次涉及到分割条件,Mysql提供如下分割条件,不同的分割条件就是不同的表分区类型:
  1. RANGE分区。就是按照某列的值的范围作为分区条件。如分区表有一个列 a表示年龄,类型为int,则可以将 a的值<3的行数据作为一个分区,a的值<6的行数据作为一个分区。
  2. LIST分区。和RANGE分区类似,不过列的值不是连续区间而是离散区间。如一个分区表有一个列 a 表示省份, 类型为字符串,则可以将 a的值属于("北京","上海")的作为一个分区,可以将 a的值属于("浙江","江西")的作为一个分区。
  3. HASH分区。就是将某列作为key,hash函数的输出作为行数据存放的分区号。如分区表有一个列 a 表示金额,类型为int,分区表分区个数为10,则 hash(a)的值就作为行数据存放的分区号。
  4. KEY分区。KEY分区其实跟HASH分区差不多,不同就在于计算hash值的时候KEY分区允许多列作为key,而HASH分区只允许一列作为key。采用的hash函数也不同。
下面我们创建分区表来演示一下。执行如下语句创建表和分区。
CREATE TABLE test_range_partition(
    id INT auto_increment,
    createdate DATETIME,
    primary key (id,createdate)
) 

PARTITION BY RANGE (TO_DAYS(createdate) ) (
   PARTITION p201801 VALUES LESS THAN ( TO_DAYS('20180201') ),
   PARTITION p201802 VALUES LESS THAN ( TO_DAYS('20180301') ),
   PARTITION p201803 VALUES LESS THAN ( TO_DAYS('20180401') ),
   PARTITION p201804 VALUES LESS THAN ( TO_DAYS('20180501') ),
   PARTITION p201805 VALUES LESS THAN ( TO_DAYS('20180601') ),
   PARTITION p201806 VALUES LESS THAN ( TO_DAYS('20180701') ),
   PARTITION p201807 VALUES LESS THAN ( TO_DAYS('20180801') ),
   PARTITION p201808 VALUES LESS THAN ( TO_DAYS('20180901') ),
   PARTITION p201809 VALUES LESS THAN ( TO_DAYS('20181001') ),
   PARTITION p201810 VALUES LESS THAN ( TO_DAYS('20181101') ),
   PARTITION p201811 VALUES LESS THAN ( TO_DAYS('20181201') ),
   PARTITION p201812 VALUES LESS THAN ( TO_DAYS('20190101') )
);

创建了一个分区表test_range_partition,其中有12个分区,第一个分区p201801的记录的创建时间小于20180201,第二个分区p201802的记录的创建时间小于20180301,依次类推。这是一个按时间的range分区。分区表的数据文件如下所示。

执行如下SQL插入语句。
insert into test_range_partition (createdate) values ('20180105');
insert into test_range_partition (createdate) values ('20180205');
insert into test_range_partition (createdate) values ('20180206');
insert into test_range_partition (createdate) values ('20180305');
insert into test_range_partition (createdate) values ('20180405');
insert into test_range_partition (createdate) values ('20180505');
insert into test_range_partition (createdate) values ('20180605');
insert into test_range_partition (createdate) values ('20180705');
insert i
执行 explain select * from test_range_partition where createdate = '20180105',输出信息如下。
该方式和全表扫描类似,但扫描的对象不同,index方式扫描的是索引树。尽管ALL和index方式都是全表扫描,但通常索引文件比数据文件小,因此index方式比ALL要快。如执行 explain select name from user_info,输出信息如下。

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Java开发之数据库索引篇,适合所有求职开发岗的同学~ 本专刊购买后即可解锁所有章节,故不可以退换哦~

全部评论

相关推荐

11-03 12:40
中山大学 Java
勇敢的突尼斯海怪选钝...:楼主这拒意向话术好得体呀 !求问HR回复态度咋样呀
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务