写错 一条 SQL 语句,被经理邀爬山?
积累知识,胜过积蓄金银!毕竟在##column_title##开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《写错 一条 SQL 语句,被经理邀爬山?》,就带大家讲解一下MySQL、Java、后端知识点,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~
前戏
SQL 写的秒,涨薪呱呱叫!
新来的实习生小杨写了一条 SQL 语句
SELECT wx_id from `user` WHERE wx_id = 2
当小杨迫不及待准备下班回家的时候,隔壁的王经理一把抓住了小杨,并用 EXPLAIN 命令教育了小杨,小杨流下了没有文化的泪水。
这条 SQL 语句中,wx_id 是具有索引的,但是王经理查出来的结果却是这样的

王经理的教育
小杨仔细一瞅 key 字段显示为 Null,很明显这条SQL语句没有走索引。
小杨心想“糟糕,又写错 SQL 语句了,这下又要面临运维和经理的混合双打了, 不行我得立马改下这条 SQL 语句,让我想想哪里出错了”

小杨脑袋瓜疯狂乱撞,仔细回想表结构,忽然想到,wx_id 字段是 varchar 类型,自己查询的时候竟然没有加引号。
小杨一把抢过经理手里的键盘,往 wx_id 的查询条件上加了引号,结果

经理微微一笑问道“你知道为什么为什么加了引号就走了索引吗?如果字段是 int 类型,那么查询的时候需不需要加引号呢?又是为什么呢?”
正餐来了
小杨被问的呆在原地,无法回答。
经过小杨研究发现,如果字段是 varchar类型,等号右侧必须加引号才走索引;如果字段是 int 类型,那么等号右侧加不加引号都是会走索引的。
什么?你不相信小杨说的话,有图有真相。(bonus 字段类型为int)

真相图
但是结论出来,还是无法回答经理的夺命三连问。苦恼的小杨打开了公众号 码儿嘟嘟骑 想要寻求答案。

这不是广告
小杨搬来了答案
码儿嘟嘟骑的号主告诉小杨
在 MySQL 查询中,当查询条件左右两侧类型不匹配的时候会发生隐式转换
也就是说 SELECT wx_id from `user` WHERE wx_id = 2 等价于 SELECT wx_id from `user` WHERE CAST(wx_id AS signed int) = 2
一旦对索引字段做函数操作,MySQL 会放弃使用索引
所以如果字段是 varchar 类型,等号右侧必须加引号才走索引,否则由于隐式转换,MySQL 会放弃使用索引。那么凭什么 int 加不加引号都可以使用索引呢?
那是因为 int 类型的数字只有2能转化为'2',是唯一确定的。所以虽然需要隐式转换,但不影响使用索引
小杨追问:“你还能在告诉我一些隐式转换的知识吗?”
号主反手就是一个英文文档
If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe equality comparison operator. For NULL NULL, the result is true. No conversion is needed. If both arguments in a comparison operation are strings, they are compared as strings. If both arguments are integers, they are compared as integers. Hexadecimal values are treated as binary strings if not compared to a number. If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to IN()! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type. A single-row subquery from a table or tables is not considered a constant. For example, if a subquery returns an integer to be compared to a DATETIME value, the comparison is done as two integers. The integer is not converted to a temporal value. To compare the operands as DATETIME values, use CAST() to explicitly convert the subquery value to DATETIME. If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value. In all other cases, the arguments are compared as floating-point (real) numbers.
`
贴心的我帮你们翻译成了中文
`1, 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用
对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换
2, 两个参数都是字符串,会按照字符串来比较,不做类型转换
3, 两个参数都是整数,按照整数来比较,不做类型转换
4, 十六进制的值和非数字做比较时,会被当做二进制串
5, 有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp
6, 有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数会将整数转换为 decimal 后进行比较,
如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较
7, 所有其他情况下,两个参数都会被转换为浮点数再进行比较
再分享一个隐式转换的坑
- 你是否偶尔删除了一些不知道的数据?
`mysql> select * from test;
+----+-------+-----------+
| id | name | password |
+----+-------+-----------+
| 1 | test1 | password1 |
| 2 | test2 | password2 |
| 3 | aaa | aaaa |
| 4 | 55aaa | 55aaaa |
| 5 | 1212 | aaa |
| 6 | 1212a | aaa |
+----+-------+-----------+
6 rows in set (0.00 sec)
mysql> select * from test where name = 1212;
+----+-------+----------+
| id | name | password |
+----+-------+----------+
| 5 | 1212 | aaa |
| 6 | 1212a | aaa |
+----+-------+----------+
2 rows in set, 5 warnings (0.00 sec)
mysql> select * from test where name = '1212';
+----+------+----------+
| id | name | password |
+----+------+----------+
| 5 | 1212 | aaa |
+----+------+----------+
1 row in set (0.00 sec)
`
上面的例子本意是查询id为5的那一条记录,结果把id为6的那一条也查询出来了。我想说明什么情况呢?有时候我们的数据库表中的一些列是varchar类型,但是存储的值为‘1123’这种的纯数字的字符串值,一些同学写sql的时候又不习惯加引号。这样当进行select,update或者delete的时候就可能会多操作一些数据。所以应该加引号的地方别忘记了。
总而言之
隐式类型转换有无法命中索引的风险,在高并发、大数据量的情况下,命不中索引带来的后果可不止被运维和经理混合双打哦!且写 SQL 且 EXPLAIN
今天关于《写错 一条 SQL 语句,被经理邀爬山?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

- 上一篇
- MySQL常用函数,程序员真得看看

- 下一篇
- mysql排序
-
- 兴奋的小笼包
- 写的不错,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢作者分享技术文章!
- 2023-03-06 02:24:22
-
- 落后的奇异果
- 太细致了,已收藏,感谢up主的这篇博文,我会继续支持!
- 2023-03-01 18:26:53
-
- 明亮的滑板
- 这篇技术文章出现的刚刚好,太详细了,很好,mark,关注up主了!希望up主能多写数据库相关的文章。
- 2023-02-28 11:23:24
-
- 数据库 · MySQL | 2小时前 |
- MySQL安装后如何启动和连接
- 233浏览 收藏
-
- 数据库 · MySQL | 4小时前 |
- MySQL中WHERE与HAVING的区别详解
- 259浏览 收藏
-
- 数据库 · MySQL | 7小时前 |
- MySQL数据备份方法与策略详解
- 112浏览 收藏
-
- 数据库 · MySQL | 8小时前 |
- MySQL中HAVING和WHERE的区别
- 363浏览 收藏
-
- 数据库 · MySQL | 9小时前 |
- MySQL数据归档方法与工具推荐
- 372浏览 收藏
-
- 数据库 · MySQL | 18小时前 |
- MySQL排序优化与性能提升技巧
- 236浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL缓存优化与参数调优技巧
- 107浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- 三种登录MySQL方法详解教程
- 111浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL如何用update替换字段值方法
- 145浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL缓存优化技巧与设置方法
- 330浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL中文乱码解决方法汇总
- 390浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL中文乱码解决全攻略
- 277浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 千音漫语
- 千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
- 85次使用
-
- MiniWork
- MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
- 77次使用
-
- NoCode
- NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
- 89次使用
-
- 达医智影
- 达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
- 87次使用
-
- 智慧芽Eureka
- 智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
- 83次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览