暂无图片
MySQL的全表扫描和索引优化
我来答
分享
Switchblade
2023-09-11
MySQL的全表扫描和索引优化
暂无图片 5M

SELECT COUNT(*) AS total_count , SUM(CASE WHEN chat_status IN ('hold', 'open') THEN 1 ELSE 0 END) AS open_count , SUM(CASE WHEN chat_status IN ('pending', 'available') THEN 1 ELSE 0 END) AS queue_count , SUM(CASE WHEN chat_status = 'closed' THEN 1 ELSE 0 END) AS closed_count , SUM(CASE WHEN chat_status IN ('available', 'pending') AND active_node_id IS NOT NULL THEN 1 ELSE 0 END) AS pathway_count , SUM(CASE WHEN chat_status IN ('available', 'pending') AND active_survey_response_id IS NOT NULL THEN 1 ELSE 0 END) AS survey_count , group_idFROM text_chatWHERE client_id = 370GROUP BY client_id, group_id;

全表扫描的执行时间是1秒,

mysql> explain SELECT -> COUNT(*) AS total_count -> , SUM(CASE WHEN chat_status IN ('hold', 'open') THEN 1 ELSE 0 END) AS open_count -> , SUM(CASE WHEN chat_status IN ('pending', 'available') THEN 1 ELSE 0 END) AS queue_count -> , SUM(CASE WHEN chat_status = 'closed' THEN 1 ELSE 0 END) AS closed_count -> , SUM(CASE WHEN chat_status IN ('available', 'pending') AND active_node_id IS NOT NULL THEN 1 ELSE 0 END) AS pathway_count -> , SUM(CASE WHEN chat_status IN ('available', 'pending') AND active_survey_response_id IS NOT NULL THEN 1 ELSE 0 END) AS survey_count -> , group_id -> FROM text_chat -> WHERE client_id = 370 -> GROUP BY client_id, group_id;
+------+-------------+-----------+------+---------------+------+---------+------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+------+---------------+------+---------+------+--------+----------------------------------------------+
| 1 | SIMPLE | text_chat | ALL | NULL | NULL | NULL | NULL | 998707 | Using where; Using temporary; Using filesort |
+------+-------------+-----------+------+---------------+------+---------+------+--------+----------------------------------------------+
1 row in set (0.21 sec)




CREATE TABLE `text_chat` ( `phone_number` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', `client_id` mediumint(8) unsigned NOT NULL DEFAULT 0, `group_id` int(10) unsigned DEFAULT NULL, `active_group_id` int(10) unsigned DEFAULT NULL, `client_number` varchar(25) COLLATE utf8_unicode_ci DEFAULT NULL, `contact_id` int(10) unsigned DEFAULT NULL, `opened_datetime` datetime DEFAULT NULL, `chat_status` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'closed' COMMENT 'open, closed, hold, pending', `status_datetime` datetime DEFAULT NULL, `active_user_id` int(10) DEFAULT NULL, `active_interaction_id` int(10) unsigned DEFAULT NULL, `active_node_id` int(10) unsigned DEFAULT NULL, `active_survey_response_id` int(10) unsigned DEFAULT NULL, `pathway_completed` tinyint(1) DEFAULT 0, `datetime_last` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), PRIMARY KEY (`phone_number`,`client_id`), KEY `active_user_id` (`active_user_id`), KEY `chat_status` (`chat_status`), KEY `active_user_id_2` (`active_user_id`,`chat_status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


mysql> select count(distinct client_id) from text_chat;
+---------------------------+
| count(distinct client_id) |
+---------------------------+
| 712 |
+---------------------------+
1 row in set (0.54 sec)

mysql> select count(distinct group_id) from text_chat;
+--------------------------+
| count(distinct group_id) |
+--------------------------+
| 1476 |
+--------------------------+
1 row in set (0.59 sec)

mysql> select count(*) from text_chat;
+----------+
| count(*) |
+----------+
| 1010692 |
+----------+
1 row in set (0.44 sec)


尝试过的索引

idx_cid(client_id)

idx_gid(group_id)

idx_cid_gid(client_id,group_id)

均没有全表扫描快,请问如何优化或者改写

idx_gid_cid(group_id,client_id)

我来答
添加附件
收藏
分享
问题补充
2条回答
默认
最新
大大刺猬

从业务逻辑优化吧, 比如where限制下phone_number, 我试了下你这个SQL, 速度还行啊. 0.33秒
image.png

暂无图片 评论
暂无图片 有用 2
打赏 0
暂无图片
Switchblade
题主
2023-09-11
可能是数据不一样,有改写思路吗
小洋

1)看了下你这个SQL,写法不是标准的SQL语法 ;select 里面没看到client_id字段, group by 里面有 client_id字段, where里面指定了client_id=370条件; 其实group by 里面可以去掉 client_id 字段

2)text_chat 表总记录1010692, client_id 字段去重712个, 说明client_id 一个值包含很多数据, count(*)下  client_id=370 记录 占表text_chat 表总记录百分之多少

3)case 里面的 chat_status 字段有没有建立索引,去重有多少个

暂无图片 评论
暂无图片 有用 0
打赏 0
回答交流
Markdown


请输入正文
提交
相关推荐
mysql从库复制中断,gtid出现gap是怎么回事
回答 9
对,关键问题是,为什么purge前没有传过来。数据库是一直实时同步。
mysql一张7000w数据的大表,添加字段,有啥高效的办法,且保障不影响生产业务
回答 1
关键看版本。8没事。8以下真没什么不影响业务的好方法,只能说影响小的有PT那个工具。如果可以停机,就申请停机加一下吧。 还有一个方法有点危险,就是如果是双主的话,或者保证一致性的前提下,加另
为什么MYSQL子查询同名列会报错?
回答 2
已采纳
执行计划的区别,oracle为了提升count()性能,可以不去处理子查询里的每个字段,此时有没有重复字段也无所谓,因为它只需要知道有多少数据就行了
performance_schema.keyring_component_status 这个表在什么配置或者做什么操作才能生成?
回答 1
performanceschema.keyringcomponentstatus 表是MySQL8.0及更高版本中用于监控和诊断密钥环组件状态的表。这个表的存在和可用性通常与MySQL的密钥
当关系中存在多个候选关键字时,选择主键的基本原则是什么?
回答 1
已采纳
⚫候选键中包含的属性数量越少越好。⚫候选键中的值从不或很少发生变化。⚫如果候选键的属性是字符型,那么属性值中包含的字符个数越少越好。⚫如果候选键的属性是数值型,那么属性值中的最大值越小越好。⚫选择最方
有没有什么方法可以实时检测 mysql 数据库中某个值是否发生改变?
回答 1
触发器?
关于explain执行计划,explain_type 有哪几个类型? A.EXTENDED B.PARTITIONS C.JSON D.FORMA T = format_name
回答 1
已采纳
ABDexplaintype有三个类型,EXTENDED、PARTITIONS、FORMATformatname,三个只能同时使用一个,否则报语法错误,分别表示含义如下(注意:5.7开始默认启用EXT
用maridb做主备,如果备服务器宕机了,如何才能重新做成集群?
回答 1
已采纳
就当没有过,重建搭建,物理备份拉起来,然后追日志。
MySQL a表拼接字段怎么更新到b表?
回答 2
问题表述模糊不清。updateajoinbona.idb.idsetb.colnameconcat(a.colname,a.colname2)
MySQL如何在参数配置文件中保存账户和密码?
回答 2
已采纳
MySQL的参数配置文件里的参数是按对应的程序名进行分组的,组名放在[]中。如[mysqld]和[mysql]组分别对应mysqld服务和mysal客户端程序。[client]参数组对应所有的客户端程