首页 > 数据库 > 数据库开发技术 > 群友:存储过程也有字符集的吗?学到了
本周六直播课《业务并发,锁和死锁》
进技术交流群见文末海报
====正文分割线===
事情是这样的,先是有一个群友问了个好问题
(在我看来,有复现步骤,有疑问点,就算好问题)
以下语句构造数据以后,执行 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))beginexplain select * from t where cellLabelCode =v;end;;delimiter ;call p('bbbbb');
(这个问题本身难度不大,但是符合上面说的提问方式,点赞👍)
有两个线索:
1. 表结构里的utf8mb3是个显眼包。我们知道以前用utf8的,现在新建的表,都建议直接使用utf8mb4了,这个mb3很容易引起关注 ----确实也是正确的入口;
2. 执行call p('bbbbb'); 的时候有warning,执行个show warnings也有答案

|
我们来看看是原因是什么叭。 where cellLabelCode =v 这里字符集不同,就要做转换。转换的方向是按数据长度增加的方向。因此这里这里语句就被改写成 where convert(cellLabelCode using utf8mb4) =v。 这就触发了另一个规则啦,对字段做计算会导致索引失效,因此就只能全表扫描呀。
|
以下两张图是群里讨论的,直接贴了,修改方案之一如下。
同时引出另一位群友的回复:


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

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