修改 decimal 默认值为0.00 sql_被经理邀请去“爬山”,只是因为我写错了一条SQL语句?...

93c5d9012cbfff816f03b392d5f3493d.png
作者:isysc1
链接:https://juejin.im/post/5f06a2156fb9a07e5f5180df
来源:掘金

前戏

SQL 写的妙,涨薪呱呱叫!

新来的实习生小杨写了一条 SQL 语句

SELECT wx_id from `user` WHERE wx_id = 2

当小杨迫不及待准备下班回家的时候,隔壁的王经理一把抓住了小杨,并用 EXPLAIN 命令教育了小杨,小杨流下了没有文化的泪水。

这条 SQL 语句中,wx_id 是具有索引的,但是王经理查出来的结果却是这样的

995b1dfa309847af4f3383ed51084dda.png
王经理的教育

小杨仔细一瞅 key 字段显示为 Null,很明显这条SQL语句没有走索引。

小杨心想“糟糕,又写错 SQL 语句了,这下又要面临运维和经理的混合双打了, 不行我得立马改下这条 SQL 语句,让我想想哪里出错了”

318f61a1813cfd3bec06a85e642961c0.png

小杨脑袋瓜疯狂乱撞,仔细回想表结构,忽然想到,wx_id 字段是 varchar 类型,自己查询的时候竟然没有加引号。

小杨一把抢过经理手里的键盘,往 wx_id 的查询条件上加了引号,结果

e55cabf8b2276f5d890c69a38c97834e.png

果然这条 SQL 语句开始走了索引。小杨沾沾自喜以为解决了个天大的 Bug。

经理微微一笑问道“你知道为什么为什么加了引号就走了索引吗?如果字段是 int 类型,那么查询的时候需不需要加引号呢?又是为什么呢?”

正餐来了

小杨被问的呆在原地,无法回答。

经过小杨研究发现,如果字段是 varchar类型,等号右侧必须加引号才走索引;如果字段是 int 类型,那么等号右侧加不加引号都是会走索引的。

什么?你不相信小杨说的话,有图有真相。(bonus 字段类型为int)

c2a008f24c05591a40bb011880f34e6f.png
真相图
真相图

但是结论出来,还是无法回答经理的夺命三连问。

小杨搬来了答案

码儿嘟嘟骑的号主告诉小杨

在 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,并且另外一个参数是常量,常量会被转换为 timestamp6, 有一个参数是 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434080.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java课工场面向对象题p题库_面向对象设计(Java)-题库课稿.doc

面向对象程序设计 java 题库抽题规范:此题库共75道题,抽8道作为期末考试题。其中,易8道,较易33道,较难18道,难16道.按题型,第一大题抽4道&#xff0c;每道10分&#xff1b;第二大题抽2道&#xff0c;每道10分&#xff1b;第三大题抽1道&#xff0c;每道20分&#xff1b;第四大题…

opensips简介

1、引入 随着通信IP化的发展&#xff0c;IP传输的高带宽、低成本等优势使得越来越多的企业、电信运营商加快建设基于IP的各种通信应用。在通信协议IP化发展中&#xff0c;SIP协 议毫无争议地成为各大电信运营商构建其未来网络的基础协议&#xff0c;越来越多的SIP软件产品也不…

JS中关于clientWidth、offsetWidth、scrollWidth

网页可见区域宽&#xff1a; document.body.clientWidth;网页可见区域高&#xff1a; document.body.clientHeight;网页可见区域宽&#xff1a; document.body.offsetWidth (包括边线的宽);网页可见区域高&#xff1a; document.body.offsetHeight (包括边线的宽);网页正文全…

shell 执行失败重试_Uipath 机器人总是运行失败怎么办?

要知道为什么RPA机器人容易失败&#xff0c;首先了解下它和常规的应用系统有哪些区别。常规应用系统&#xff0c;就像程序员自己创造了一个世界、一个域&#xff0c;在这个世界里创造它的人就是主宰。出现BUG的风险是相对可控的&#xff0c;顶多是功能用不了。而RPA项目&#x…

c mysql安装教程视频_MySQL安装教程 - Windows安装MySQL教程 - 小白式安装MySQL教程 - 青衫慧博客...

版权声明本文转发自旧站点萧瑟云日志&#xff0c;近期考虑准备将旧站进行关闭(没有精力维护)&#xff0c;部分文章将会迁移至本站。文章发表于&#xff1a;2017-10-28 12:32:03前言上次给大家带来了SQL Server的小白式安装教程&#xff0c;这次再次带来一个MySQL的小白式安装教…

PJSIP UA分析(1)--PJSUA主函数

1 intmain(intargc, char*argv[])2 {3 do{4 app_restart PJ_FALSE; //PJ_FALSE是一个宏&#xff0c;一旦用户调用pjsua可执行文件进入该循环&#xff0c;那么默认只执行一次退出5 //如果需要再次循环&#xff0c;那么在下面函数中…

锁定表头和固定列(Fixed table head and columns)

前段时间需要这个功能&#xff0c;但是找了很多都不能完美的实现&#xff0c;不是只能锁定表头&#xff0c;就是浏览器兼容问题什么的&#xff0c;在此就自己做了一个锁定表头和列的js方法&#xff0c;依赖于JQuery。 因为方法很简单&#xff0c;就未封装成插件的形式&#xff…

游戏详细设计说明书_宜家的说明书设计脑洞太大了!

平常我们看到的说明书是像这样纯文字解说的或者是规范的文字配图这些说明书一般都是注重文字的上表达而大家熟悉的家居品牌宜家将说明书创意玩出了新境界&#xff01;↓↓↓这不&#xff0c;最近由于全球疫情严峻期间宜家的全新说明书手册搜罗了各种纸上游戏意为帮助大家打发无…

centos删除php_centos如何卸载php

查看php版本php -v查看php相关软件包#rpm -qa|grep php(视频教程推荐&#xff1a;linux视频教程)提示如下&#xff1a;#php-pdo-5.1.6-27.el5_5.3#php-mysql-5.1.6-27.el5_5.3#php-xml-5.1.6-27.el5_5.3#php-cli-5.1.6-27.el5_5.3#php-common-5.1.6-27.el5_5.3#php-gd-5.1.6-27…

PJSIP UA分析(2)--PJSUA注册

1、一开始是回调使用的函数&#xff0c;例如on_incoming_call当来电话的时候&#xff0c;pjsip会自动去调用你写的这个函数&#xff0c;前提是你在初始化pjsua的时候设置了on_incoming_call &on_incoming_call&#xff0c; 2、error_exit退出应用所需要的操作 3、main函数…

cgblib 代理接口原理_Java开发者你还不知道?告诉你Dubbo 的底层原理,面试不再怕...

前言平常我们在构建分布式系统的时候&#xff0c;一般都是基于 Dubbo 技术栈或者是SpringCloud 技术栈来做。早期其实最先比较流行的是Dubbo&#xff0c;我记得我们当时有个部分的老大就是用的是Dubbo 来构建的一个系统&#xff0c;到后面才出来的 SpringCloud&#xff0c;由于…

包含对流环热,热流边界,等温边界的稳态热传导方程的FEM求解。

以下面的问题为例&#xff1a;对于如图所示的平面传热问题&#xff0c; 若上端有给定的热流-2W/m2&#xff0c;即从下往上传输热量&#xff0c;结构下端有确定的温度100&#xff0c;周围介质温度为20&#xff0c;在两侧有换热&#xff0c;换热系数为α100W/㎡/K&#xff0c;热导…

php安装扩展步骤,PHP扩展安装方法步骤解析

php扩展安装方法极简单. 也遵循3大步.但多出一个phpize的步骤.1.pecl.php.net 在右上解的输入框 中输入需要的扩展 比如 redis2.搜索完成后会看到两个蓝色的框 . 下方有个表格. 表格内容如 search results (1 of 1) 再下面有一行不起眼的结果. 其中就有一个redis(搜索什么显示什…

python生成动态二维码实例_python生成动态个性二维码(示例代码)

1 安装工具 2 生成普通二维码 3 带图片的二维码 4 动态 GIF 二维码 5 在Python程序中使用 一、安装 首先在python环境下运行&#xff0c; 打开cmd进入python27 进入scripts 然后在scripts输入命令&#xff1a;pip install myqr二、 生成普通二维码 安装了 myqr 之后&#xff0c…

MFC取消菜单栏

在CMainFrame的OnCreate()中添加如下代码&#xff1a;//去掉标题栏及其他样式SetWindowLong(this->m_hWnd,GWL_STYLE,0);//去掉边框及其他样式SetWindowLong(this->m_hWnd,GWL_EXSTYLE,0);//取消菜单栏this->SetMenu(NULL); 在CView中的OnCreate()中也去掉边框 //去掉…

php的cookie变量作用,PHP语言中cookie的作用

PHP语言中cookie的作用时间&#xff1a;2015-11-9Cookie的概念最早是由Netscape在1994年提出来的,它是保存在浏览器中的小信息包,更确切地说,Cookie是保存在客户端硬盘里的,由字符串组成的小文本文件.文本文件的命令格式如下;用户名网站地址[数字].txt举个例子,如果用户在系统盘…

如何查看Linux版本号(内核版本号和发行版本号)

首先&#xff0c;要分清内核版本号和发行版本号的区别。 因为所有linux都是使用kernel.org上来的内核来作为发行版的基础的&#xff0c;所以内核版本号的高低大致能体现该linux版本的新旧。 而发行版本的版本号完全是各发行商自己定义的&#xff0c;不能用来和其它发行版本的版…

matlab武汉理工大学数值分析线性函数拟合实验_「首席架构师推荐」数值计算库精选...

这是一个著名的数值库列表&#xff0c;这些库用于软件开发中执行数值计算。它不是一个完整的列表&#xff0c;而是一个包含Wikipedia上文章的数字库列表&#xff0c;很少有例外。典型库的选择取决于一系列不同的需求&#xff0c;例如:期望的特性(例如:大维线性代数、并行计算、…

DCE和DTE的区别

DCE&#xff08;数据通信设备或者数据电路终端设备&#xff09;&#xff1a;该设备和其与通信网络的连接构成了网络终端的用户网络接口。它提供了到网络的一条物理连接、转发业务量&#xff0c;并且提供了一个用于同步DCE设备和DTE设备之间数据传输的时钟信号。调制解调器和接口…

php 弹出保存对话框,如何在不将页面留在PHP中的情况下强制保存为对话框?

当使用StijnvanBael的代码时,请小心,它会使您面临一些严重的安全漏洞攻击。尝试以下方法:--- download.php ---$allowed_files array(file.pdf, otherfile.pdf);if (isset($_REQUEST[file]) && in_array($_REQUEST[file], $allowed_files)){$filename $_REQUEST[file…