ChatGPT3.5使用体验( 六 )


5、ICP 的加速效果取决于在存储引擎内通过 ICP 筛选掉的数据的比例;
6、MySQL 5.6版本的不支持分表的 ICP 功能,5.7版本的开始支持;
7、当 SQL 使用覆盖索引时,不支持 ICP 优化方法 。
给字符串字段加索引
给字符串创建所以可以考虑使用前缀索引,定义好长度,就可以做到既节省空间,又不用额外增加太多的查询成本 。
实际上,在创建索引的时候,需要关注区分度,区分度越高越好 。因为区分度越高,意味着重复的键值越少 。因此,我们可以通过统计索引上有多少个不同的值来判断要使用多长的前缀 。
可以使用下面这个语句,算出这个列上有多少个不同的值:
select count(distinct email) as L from SUser;
然后,依次选取不同长度的前缀来看这个值,比如我们要看一下4~7个字节的前缀索引,可以用这个语句:
select count(distinct left(email,4))as L4,count(distinct left(email,5))as L5,count(distinct left(email,6))as L6,count(distinct left(email,7))as L7,from SUser;
当然,使用前缀索引很可能会损失区分度,所以你需要预先设定一个可以接受的损失比例,比如5% 。然后,在返回的L4~L7中,找出不小于L * 95%的值,假设这里L6、L7都满足,你就可以选择前缀长度为 6 。
不过需要注意的是使用了前缀索引就不能使用覆盖索引对查询性能的优化了 。
如果前缀索引的区分度不是很高,还有没有其他的方法了呢?
1、使用倒序存储;
例如身份证信息,前几位大部分都是相同的,区分度不高,但是最后面即为有很高的区分度,那么就可以把身份证的信息,倒序存储 。
select field_list from t where id_card = reverse('input_id_card_string');
2、使用 hash 字段;
可以在表上新建一个字段,用来保存身份证的校验码,同时在该字段上建立索引 。
每次插入数据除了记录省份证信息,还把身份证的 hash 码,也存储起来,这样查询的使用,通过这个 hash 码,就能很快的找到身份证信息了 。
不过因为 hash 码会存在相同的情况,所以查询的条件本上还需要带上身份证号码 。
select field_list from t where id_card_crc=crc32('input_id_card_string') and id_card='input_id_card_string'
MySQL 中的 count 查询
MySQL中的 count(*) 的实现方式
中count(*)、count(主键id)和count(1),返回的都是满足条件的结果集的总行数,count(字段),则表示返回满足条件的数据行里面,参数“字段”不为 NULL 的总个数 。
count(主键id):引擎会遍历整张表,把每一行的 id 值取出来,返回给层,层拿到 id 后,判断是不可能为空的,就按行累加;
count(1): 引 擎遍历整张表,但不取值 。层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加;
count(字段):
1、如果这个“字段”是定义为not null的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加;
2、如果这个“字段”定义允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出来再判断一下,不是 null 才累加 。
count(*): 这个统计专门做了优化,不用取值,count(*)肯定不是 null,按行累加 。
所以按照效率排序count(字段) 。
MySQL 中的 order by
MySQL 中的排序是我们经常用到的操作,下面来研究下排序的实现过程 。
CREATE TABLE `t_user_city` (`id` int(11) NOT NULL,`city` varchar(16) NOT NULL,`name` varchar(16) NOT NULL,`age` int(11) NOT NULL,`addr` varchar(128) DEFAULT NULL,PRIMARY KEY (`id`),KEY `city` (`city`)) ENGINE=InnoDB;insert into t_user_city values(1, "郑州", "小明",12,"郑州大街6666号201");insert into t_user_city values(2, "杭州", "小红",20,"杭州大街6666号201");insert into t_user_city values(3, "杭州", "小白",19,"杭州大街6666号201");insert into t_user_city values(4, "上海", "张三",24,"上海大街6666号201");insert into t_user_city values(5, "上海", "李四",25,"上海大街6666号201");insert into t_user_city values(6, "上海", "王五",26,"上海大街6666号201");insert into t_user_city values(7, "上海", "王六",29,"上海大街6666号201");insert into t_user_city values(8, "郑州", "小明001",12,"郑州大街6666号201");insert into t_user_city values(9, "郑州", "小明002",12,"郑州大街6666号201");insert into t_user_city values(10, "郑州", "小明003",12,"郑州大街6666号201");