探索MySQL索引(单表百万)优劣对比主键索引,联合索引(顺序)
- 4832
- MySQL
- 36
- super_dodo
- 2017/03/01
现在我们有一张简易的用户表,目前有测试数据119万条。今天闲来无事,所以想测试一下WHERE条件中一个字段或者多个字段(排序),之间的多个主键索引联合索引的比较。一切以你自己的环境和数据量为参考。以下情况仅为dodo的个人电脑环境下面的测试。欢迎拍砖和指引。另外此处的为MyISAM的引擎。
//查看一下默认的表结构,主键自增,主键索引,没有其他索引 SHOW CREATE TABLE user_list; CREATE TABLE `user_list` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(20) NOT NULL COMMENT '昵称', `phone` varchar(20) DEFAULT NULL COMMENT '手机号', `type` tinyint(3) unsigned NOT NULL COMMENT '用户类型1-6', `sex` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '用户性别 0未知 1男 2女', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1199797 DEFAULT CHARSET=utf8mb4 //查看一下记录数目--共119万+ SELECT count(*) FROM user_list; 1199796 //时间: 0.001s
基本情况介绍结束了,首先我们来测试对比一下,WHERE字段中只有一个查询字段的情况下.这个时候我们可以用主键索引或普通索引.
//默认情况下,不在type字段上建索引的情况下 SELECT SQL_NO_CACHE FROM user_list WHERE type=3; //EXPLAIN索引 type:ALL rows:1199796 Extra:Using where //受影响的行: 0 //时间: 0.413s //主键索引的情况下 PRIMARY KEY (`id`,`type`) SELECT SQL_NO_CACHE * FROM user_list WHERE type=3; //EXPLAIN索引 type:ALL rows:1199796 Extra:Using where //受影响的行: 0 //时间: 0.406s //普通索引的情况下 PRIMARY KEY (`id`), KEY `idx_type` (`type`) SELECT SQL_NO_CACHE * FROM user_list WHERE type=3; //EXPLAIN索引 type:ref rows:135070 Extra: //受影响的行: 0 //时间: 0.899s //结论有点神奇:排除数据层面的影响,没有建索引和建了主键索引的情况下,差距不大。有主键索引的略占优,优势不大。 //然而建了普通索引的,查询用到了所以,查询记录也少了,但是查询时间反而翻倍了。比较疑惑。
接下来我们来考量测试联合索引的方式的性能。我们以type和sex作为两个必须的查询条件。
//比较建索引字段前后是否有影响到结果 KEY `idx_type_cate` (`type`,`sex`) SELECT SQL_NO_CACHE * FROM user_list WHERE type=3 AND sex=2; SELECT SQL_NO_CACHE * FROM user_list WHERE sex=2 AND type=3; //EXPLAIN索引 type:ref rows:60937 Extra: //受影响的行: 0 //时间: 0.316s //结论:两者之间的在查询语句WHERE的条件上面前后顺序不一样,不影响索引的使用和查询扫描的行数,以及查询响应的结果。 //建联合索引的时候建议把离散度大的放在前面,这样可以减少扫描的行数。 //分开建索引,非联合索引 KEY `idx_type` (`type`),KEY `idx_sex` (`sex`) SELECT SQL_NO_CACHE * FROM user_list WHERE type=3 AND sex=2; //EXPLAIN索引 type:ref rows:60937 Extra:Using where possible_keys:idx_type,idx_sex //受影响的行: 0 //时间: 0.776s SELECT SQL_NO_CACHE * FROM user_list WHERE sex=2 AND type=3; //EXPLAIN索引 type:ref rows:60937 Extra:Using where possible_keys:idx_type,idx_sex //受影响的行: 0 //时间: 0.752s 结论:当要查询两个字段的时候请一定要建联合索引,且根据离散度不同,离散度大的排在前面。
PS:刚刚咨询了一下同事,猜测是type字段才6个值,离散度太低,造成的测试不太精确。明天我会给phone字段加索引测试。
友情链接:探索MySQL索引(单表百万)优劣对比主键索引VS普通索引
不要在一件别扭的事上纠缠太久。纠缠久了,你会烦,会痛,会厌,会累,会神伤,会心碎。实际上,到最后,你不是跟事过不去,而是跟自己过不去。
相关阅读
- 通过Google API客户端访问Google Play帐户报告PHP库
- PHP执行文件的压缩和解压缩方法
- 消息中间件MQ与RabbitMQ面试题
- 如何搭建一个拖垮公司的技术架构?
- Yii2中ElasticSearch的使用示例
热门文章
- 通过Google API客户端访问Google Play帐户报告PHP库
- PHP执行文件的压缩和解压缩方法
- 消息中间件MQ与RabbitMQ面试题
- 如何搭建一个拖垮公司的技术架构?
- Yii2中ElasticSearch的使用示例
最新文章
- 通过Google API客户端访问Google Play帐户报告PHP库
- PHP执行文件的压缩和解压缩方法
- 消息中间件MQ与RabbitMQ面试题
- 如何搭建一个拖垮公司的技术架构?
- Yii2中ElasticSearch的使用示例