我的编程空间,编程开发者的网络收藏夹
学习永远不晚

子查询更新操作的坑

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

子查询更新操作的坑

子查询我相信大部分人都写过,但是昨天遇到一个比较坑的问题,由于有较好的备份,很短时间就恢复了误操作数据,但是这个问题值得分享。
首先建立如下测试表:
CREATE TABLE course (
student_id INT(11),
course VARCHAR(20)
);
INSERT INTO course VALUES ('1', '测试1');
INSERT INTO course VALUES ('2', '测试2');
INSERT INTO course VALUES ('3', '测试3');

CREATE TABLE student (
id INT(11),
name VARCHAR(20)
) ;
INSERT INTO student VALUES ('1', 'jiate');
INSERT INTO student VALUES ('2', 'haoshen');
INSERT INTO student VALUES ('3', 'leishen');
INSERT INTO student VALUES ('4', 'tetui');

子查询更新操作的坑

现在我们执行如下查询操作:
SELECT FROM student WHERE id IN (SELECT id FROM course)
子查询更新操作的坑
这个结果很明显,多了一条。而在昨天,我们开发写的是个update 操作,也是就:update student set name='特腿' where id in (select id from course) 本来更新1000条的数据,开发直接误更新了40万条。
仔细排查后,发现刚才两条sql发现 course 中根本就不存在id列,那么刚才那两条sql为啥没有抛出id报错,而是直接全表匹配了?
我们 desc extended 看看优化器究竟干了什么?
DESC EXTENDED SELECT
FROM student WHERE id IN (SELECT id FROM course)

SHOW WARNINGS

子查询更新操作的坑
第一行1276 大意是说第二个查询中的 id 列在第一个表中被解析到
第二行就是解析器解析后的sql,我们贴出来看看
SELECT
yhtest.student.id AS id,
yhtest.student.name AS name
FROM
yhtest.student semi
JOIN (yhtest.course)
WHERE (
yhtest.student.id = yhtest.student.id
)

也就是说我们这个子查询中的id 列被解析为了主表的id 列,这样,where 条件是一个恒成立的条件,所以导致我们的查询过结果是a表的全表结果,而这也是这样的查询不抛错的原因。
子查询中的字段,首先会在子查询中查找,1)如果子查询中没该字段,则会去外层主表查找,如果能找到,也不会抛错! 2)如果子查询和主表中都没有该字段,则会抛错。
这其实是一个比较不理想的结果,如果我们无意中错误是update操作,那么这个结果太糟糕。
这个我们提了两个醒:
1)做数据库操作之前,最好都备份
2)平时写sql的时候,子查询尽量都写成表关联的形式,表关联形式,如果出现这种错误,会直接抛出错误。子查询形式,虽然好懂,一目了然,但是性能一般不大好,再一个,如果掉进了以上这种误更新坑中......
3)在不同版本的数据库对于子查询的优化操作也是不尽相同,性能差异在不同版本之间还是比较明显的。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

子查询更新操作的坑

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

操作更新Excel工作表时,必须使用一个可更新的查询

查询是一种用于从数据库中检索数据的技术,而Excel工作表并不是数据库。因此,不需要使用可更新的查询来更新Excel工作表。相反,您可以直接在Excel中进行更新,例如通过更改单元格的值、插入行或列、删除数据等。如果您想通过查询从数据库中检
2023-09-26

如何用php操作mysql更新查询结果

这篇文章主要介绍“如何用php操作mysql更新查询结果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何用php操作mysql更新查询结果”文章能帮助大家解决问题。1. 使用AJAX在现代前端开发
2023-07-05

使用elasticsearch原子操作更新

本篇文章向大家介绍《使用elasticsearch原子操作更新》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。问题内容func (d *Dynamic) Like(ctx *gin.Context) {var (req messa
使用elasticsearch原子操作更新
2024-04-04

System.Data.OleDb.OleDbException:操作必须使用一个可更新的查询

这个异常表示执行的操作需要使用可更新的查询。在使用OleDb进行数据库操作时,有一些情况下可能会出现这个异常。以下是一些可能引发此异常的情况:1. 查询语句不支持更新操作:有些查询语句是只读的,例如SELECT语句,尝试在这样的查询语句上执
2023-09-26

MySQL联表查询基本操作之left-join常见的坑

概述 对于中小体量的项目而言,联表查询是再常见不过的操作了,尤其是在做报表的时候。然而校对数据的时候,您发现坑了吗?本篇文章就 mysql 常用联表查询复现常见的坑。 基础环境 建表语句DROP TABLE IF EXISTS `role`
2022-05-19

同时对同一张表进行插入、查询和更新操作

可能会出现以下问题: 数据不一致:如果在查询和更新操作之间发生了插入操作,查询操作可能会返回不完整的数据。同样,如果在插入和更新操作之间发生了查询操作,更新操作可能会使用不完整的数据进行更新。 死锁:如果多个线程同时访问同一张表,并且它们对
2023-08-18

深入解析Golang中链表的插入、删除、更新和查询操作

Golang 中链表的增删改查操作详解链表(linked list)是一种常见的数据结构,它由一组结点(node)组成,每个结点包含数据和指向下一个结点的指针。相比于数组,链表的优势在于插入和删除操作的时间复杂度为 O(1),而不受链表长
深入解析Golang中链表的插入、删除、更新和查询操作
2024-01-29

Hive如何处理复杂的JOIN操作和子查询

Hive处理复杂的JOIN操作和子查询时,可以通过以下方法来优化查询性能:使用合适的JOIN算法:Hive支持多种JOIN算法,包括MapJoin、SortMergeJoin和BucketMapJoin。根据数据量和数据分布情况选择合适的J
Hive如何处理复杂的JOIN操作和子查询
2024-03-11

编程热搜

目录