微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MySQL 字符集不一致导致索引失效的一个真实案例

字符集


大家好,我是只谈技术不剪发的 Tony 老师。今天给大家分析一个由于 MysqL 字符集不一致导致索引失效的案例。

问题描述

有个朋友给我发来一个问题,说是他们的系统有几十万用户,某个查询需要 5 秒以上的时间才能返回,同时服务器 cpu 资源占用率将近 100%。这个对于用户的线上操作影响非常大,那么我们就来看看如何分析和解决这个慢查询问题。

为了便于说明问题,我们对表结构进行了简化:

create table customer(
  cid int auto_increment primary key,
  cname varchar(50) not null,
  register_time datetime not null,
  recommender varchar(50) character set utf8
) engine=innodb default charset=utf8mb4;

create unique index uk_customer_cname on customer(cname);

insert into customer(cname, register_time, recommender) values('张三', Now(), '');
insert into customer(cname, recommender) values('李四', '张三'),('王五', '李四');

customer 是用户表,其中 cid 是主键;cname 上有一个唯一索引;recommender 是用户的推荐人。

实际查询涉及了很多表,经过简化之后存在性能问题的语句如下:

select c.*
from customer c
join customer r on (c.recommender = r.cname )
where r.cid = 1
and c.register_time between Now() - interval 1 day and Now();

大意是查找通过某人推荐,在指定时间段内注册用户

问题分析

了解问题之后,首先我让他给我发来了 explain 执行计划:

explain
select c.*
from customer c
join customer r on (c.recommender = r.cname )
where r.cname = '张三'
and c.register_time between Now() - interval 1 day and Now();

id|select_type|table|partitions|type |possible_keys    |key              |key_len|ref  |rows|filtered|Extra      |
--|-----------|-----|----------|-----|-----------------|-----------------|-------|-----|----|--------|-----------|
 1|SIMPLE     |r    |          |const|uk_customer_cname|uk_customer_cname|202    |const|   1|   100.0|Using index|
 1|SIMPLE     |c    |          |ALL  |                 |                 |       |     |   3|   33.33|Using where|

从结果可以看出,有一个全表扫描(type = ALL)的操作,显然这是因为 recommender 字段上缺少索引。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐