记录一次对表中长字符串列的查询优化过程

目录

1、问题的背景

2、实施方案

3、效果对比

3.1 优化之前

3.2 优化之后


1、问题的背景

     我们系统是一个互联网系统,注册用户非常多,有上百万数据,现在需要统一每个user_id注册来源的url地址,表结果如下:

CREATE TABLE `sys_reg_url_stat_v1` (
  `id` int(8) NOT NULL COMMENT '主键',
  `url` varchar(255) DEFAULT NULL COMMENT 'url',
  `reg_time` datetime DEFAULT NULL COMMENT '注册时间',
  `user_id` int(8) DEFAULT NULL COMMENT '用户Id',
  PRIMARY KEY (`id`),
  KEY `url` (`url`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='对注册来源url进行统计';

请注意,url上有一个普通索引,因为经常需要根据url查询,分组统计,所以对该索引创建了一个普通BTree索引,现在分析以下sql语句

select * from sys_reg_url_stat_v1 where url='https://www.cnblogs.com/nineyang/p/Arif';

            因为url是一个长字符串长度值通过为100个字符左右,并且url的前缘重复率为80%以上,所以不能对url前缀创建前缀索引,而如果针对整个url字符串的值创建索引,导致索引数据的前缀大量重复,索引效率不高。 

2、实施方案

          为了解决上述问题,我们增加一个新字段,url_crc32来存储url的哈希值,利用crc322哈希函数生成哈希值 ,然后在url_crc32上创建普通索引,这样索引值的选择性大大地提高,基本不重复,
哈希冲突也非常低,利用冗余提高查询查询性能。

3、效果对比


3.1 优化之前

3.2 优化之后

CREATE TABLE `sys_reg_url_stat_v2` (
  `id` int(8) NOT NULL COMMENT '主键',
  `url` varchar(255) DEFAULT NULL COMMENT 'url',
  `last_access_time` datetime DEFAULT NULL COMMENT '上次访问时间',
  `url_crc32` varchar(32) DEFAULT NULL COMMENT 'url的crc32值',
  `reg_time` datetime DEFAULT NULL COMMENT '注册时间',
  `user_id` int(8) DEFAULT NULL COMMENT '用户Id',
  PRIMARY KEY (`id`),
  KEY `url_crc32` (`url_crc32`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='对注册来源url进行统计';

可以明显的观察到key_len大大降低,fkiltered也降低了,我这里的样本数据只有200条,如果该表数据有100百万,则性能优化是相当可观的。

猜你喜欢

转载自blog.csdn.net/s2008100262/article/details/111603760