ITPub博客

首页 > 数据库 > 数据库开发技术 > 群友:存储过程也有字符集的吗?学到了

群友:存储过程也有字符集的吗?学到了

原创 数据库开发技术 作者:丁奇3306 时间:2024-10-22 10:06:28 0 删除 编辑

本周六直播课《业务并发,锁和死锁》
进技术交流群见文末海报
====正文分割线===

事情是这样的,先是有一个群友问了个好问题
(在我看来,有复现步骤,有疑问点,就算好问题)

以下语句构造数据以后,执行 call p('bbbbb') 的结果里,显示explain的结果用不上primary key。问,为什么执行存储过程没有用上索引? 
CREATE TABLE t ( cellLabelCode varchar(80) NOT NULL , field1 varchar(64) DEFAULT NULL , PRIMARY KEY (cellLabelCode)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;insert into t values('aaaaa', repeat('f1',10));insert into t values('bbbbb', repeat('f2',10));insert into t values('eeeee', repeat('f3',10));
delimiter ;;create procedure p(v varchar(80))begin explain select * from t where cellLabelCode =v;end;;delimiter ;
call p('bbbbb');

(这个问题本身难度不大,但是符合上面说的提问方式,点赞👍)

有两个线索:
1. 表结构里的utf8mb3是个显眼包。我们知道以前用utf8的,现在新建的表,都建议直接使用utf8mb4了,这个mb3很容易引起关注 ----确实也是正确的入口;

2. 执行call p('bbbbb'); 的时候有warning,执行个show warnings也有答案

我们来看看是原因是什么叭。
直接的:表是mb3而存储过程是mb4的,执行call p('bbbbb')的时候,存储过程传给explain语句的就是一个mb4的字符串啦。

where cellLabelCode =v 这里字符集不同,就要做转换。转换的方向是按数据长度增加的方向。因此这里这里语句就被改写成 where convert(cellLabelCode using utf8mb4) =v。


这就触发了另一个规则啦,对字段做计算会导致索引失效,因此就只能全表扫描呀。


好,知道了以上原因,大家可以来一起分析下,有什么修改方案叭。

【上面这段是学习群里一位00后小哥的行文语气,看人家写的就那么自然,想学一下。学得不像,装嫩失败,放弃放弃,手动旺柴】


以下两张图是群里讨论的,直接贴了,修改方案之一如下。
同时引出另一位群友的回复:


后续
问题:
存储过程有字符集吗?
怎么看存储过程的字符集?
能修改吗?
除了上图这种改法,还有别的改法能够让查询用上索引的定位能力吗?


原文作者:丁奇3306;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2024-08-07

  • 博文量
    104
  • 访问量
    44852