mysql三星索引测试

之前看了一篇关于索引的文章,说是索引的三星规则,现在就想测试测试有多大效果。

关于三星索引是这样描述的:
第一星:索引将相关的列放到一起,即在一系必要的列上建立索引,不必为在where条件里面的列都建立索引。 
二星:索引中的数据列顺序和查找中排列顺序一致。通常将选择性最高的列放到索引的最前列。
三星:索引中的列包含了查询中需要的全部列。索引包含查询所需要的数据列,不再进行全表查表(聚簇索引、覆盖索引)。
同时符合上述三个条件就记为三星索引。

对于这个一星的描述,我看不太懂是什么意思,接下来就对于二星和三星的描述进行测试。
测试前我关闭了Mysql的查询缓存功能,所以不会因为缓存导致测试结果不准的问题

现在开始测试

1.准备一个100万数据的表



2.按条件查询测试

查询从事金融行业的成年用户信息,根据用户年龄进行降序展示

SELECT 
user_name,user_sex,user_age,user_phone,user_province
FROM user 
WHERE user_job = '金融' AND user_age>=18  
ORDER BY user_age DESC

没建立索引,查询三次平均耗时查询耗时:5.7秒



3.建立索引测试

第二星:索引中的数据列顺序和查找中排列顺序一致。通常将选择性最高的列放到索引的最前列。

也就是说建立一个组合索引,索引顺序与where后面查询条件的顺序一致

ALTER TABLE user ADD INDEX index_test1(user_job,user_age);
接下来测试一下,查询三次平均耗时:13秒


反而更慢了,也不知道为啥


第三星:索引中的列包含了查询中需要的全部列。索引包含查询所需要的数据列,不再进行全表查表(聚簇索引、覆盖索引)。

也就是SELECT查询的列要全部建立在索引中

将刚才的索引删了重新建立索引:

-- 删除这个索引
ALTER TABLE user DROP index index_test1;
-- 重新建立索引,基于第三颗星的标准
ALTER TABLE user ADD INDEX index_test1(user_name,user_sex,user_age,user_phone,user_province);

查询,平均耗时:6秒


可以看实际上跟没使用索引的时候速度差不多

这是因为索引有一个最左匹配原则,我建立的这个索引在这条SQL查询中根本就没有使用,关于最左匹配原则会在文章末尾处详细说明


二星+三星:建立既符合第二颗星又符合第三颗星规则的索引进行测试

就是按照where查询条件列的顺序建立索引,同时select要展示的列也全部包含在索引中。

将刚才的索引删除,重新建立

-- 删除这个索引
ALTER TABLE user DROP index index_test1;
-- 重新建立索引,基于第二颗星和第三颗星的标准
ALTER TABLE user ADD INDEX index_test1(user_job,user_age,user_name,user_sex,user_phone,user_province);

查询平均耗时:0.17秒


快了几十倍...

4.测试总结:

100万数据,不建立索引条件查询:6秒左右


100万数据,仅仅对WHERE条件中的列建立索引:效果可能也不太理想(可能我WHERE条件中的列内容全是重复的,所以和没创建索引一样吧),如果是user_name这种重复性比较少的列建立索引,那速度肯定也会提升的非常明显

100万数据,按照顺序对WHERE条件后的列创建索引的同时,也为SELECT中要展示的列创建索引(这样就不用全表扫描了,直接走索引查询),查询耗时:0.17秒,这速度提升的太明显了

5.关于组合索引的说明

组合索引的索引文件以B-Tree格式保存,在创建组合索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。

组合索引的第一个字段必须出现在查询组句中,这个索引才会被用到。

如果有一个组合索引(col_a,col_b,col_c),下面的情况都会用到这个索引:

(1)col_a = "some value";
(2)col_a = "some value" and col_b = "some value";
(3)col_a = "some value" and col_b = "some value" and col_c = "some value";
(4)col_b = "some value" and col_a = "some value" and col_c = "some value";

对于最后一条语句,mysql会自动优化成第3条的样子。下面的情况就不会用到索引:

col_b = "aaaaaa";
col_b = "aaaa" and col_c = "cccccc";

 

参考文章:
MYSQL创建索引语句

MySQL索引的三星评估(three-star system)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值