SQL 更新会在更新运行期间影响其子查询吗?

2023-11-24

我只是编写一个复杂的更新查询,它看起来或多或少像这样:

update table join
    (select y, min(x) as MinX 
     from table
     group by y) as t1
    using (y)
set x = x - MinX

这意味着变量x基于子查询进行更新,子查询也处理变量x - but 不能这个x已被运行的更新命令修改?这不是问题吗?我的意思是,在正常编程中,您通常必须明确处理这个问题,即将新值从旧值存储到其他地方,并在工作完成后,用新值替换旧值......但是SQL数据库将如何做到这一点?

我对单一的观察或实验不感兴趣。我想要文档或 sql 标准中的一个片段来说明这种情况下定义的行为是什么。我正在使用 MySQL,但答案也适用于其他 PostgresQL、Oracle 等,尤其是一般 SQL 标准受到赞赏。谢谢!


** Edited **

从目标表中选择

From 13.2.9.8。 FROM 子句中的子查询:

FROM 子句中的子查询可以返回标量、列、行或表。 FROM 子句中的子查询不能是关联子查询,除非在 JOIN 操作的 ON 子句中使用。

所以,是的,您可以执行上述查询。

问题

这里确实有两个问题。存在并发性,或者确保没有其他人从我们脚下更改数据。这是通过锁定来处理的。处理新值与旧值的实际修改是通过派生表来处理的。

Locking

对于上面的查询,使用 InnoDB,MySQL 首先执行 SELECT,并分别在表中的每一行上获取读(共享)锁。如果 SELECT 语句中有 WHERE 子句,则只有您选择的记录才会被锁定,其中范围也会导致任何间隙被锁定。

A 读锁防止任何其他查询获取写锁,因此在读锁定时无法从其他地方更新记录。

然后,MySQL 分别获取表中每条记录的写(独占)锁。如果 UPDATE 语句中有 WHERE 子句,则只有特定记录会被写锁定,同样,如果 WHERE 子句选择了一个范围,那么您将锁定一个范围。

任何在前一个 SELECT 中具有读锁的记录都会自动升级为写锁。

A 写锁防止其他查询获得读锁或写锁。

您可以使用Innotop要看到这一点,可以通过在锁定模式下运行它,启动一个事务,执行查询(但不要提交它),然后您将在 Innotop 中看到锁。此外,您可以在没有 Innotop 的情况下查看详细信息SHOW ENGINE INNODB STATUS.

僵局

如果同时运行两个实例,您的查询很容易出现死锁。如果查询 A 获得了读锁,那么查询 B 也获得了读锁,则查询 A 必须等待查询 B 的读锁释放才能获取写锁。但是,查询 B 在完成之前不会释放读锁,并且除非它可以获得写锁,否则它不会完成。查询 A 和查询 B 陷入僵局,因此出现死锁。

因此,您可能希望执行显式表锁,既可以避免大量记录锁(占用内存并影响性能),又可以避免死锁。

另一种方法是在内部 SELECT 上使用 SELECT ... FOR UPDATE。这从所有行上的写锁开始,而不是从读取开始并升级它们。

派生表

对于内部 SELECT,MySQL 创建一个派生临时表。派生表是 MySQL 自动创建的临时表中数据的实际非索引副本(与您显式创建并可以添加索引的临时表相反)。

由于 MySQL 使用派生表,因此这是您在问题中引用的临时旧值。换句话说,这里没有魔法。 MySQL 的处理方式与您在其他地方执行的方式一样,只是使用临时值。

您可以通过对 UPDATE 语句执行 EXPLAIN 来查看派生表(MySQL 5.6+ 中支持)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL 更新会在更新运行期间影响其子查询吗? 的相关文章

随机推荐

  • UINavigationItem提示问题

    我在 UINavigationItem 上遇到提示问题 但无法解决 我有一个主视图控制器和一个详细视图控制器 当我从主控推送到详细信息时 详细信息视图控制器上会显示提示 但是 当我弹回到主视图控制器时 视图不会调整大小 并且窗口会显示出来
  • 如何更改 Sql Server 2005 中 UDT 的基本类型?

    我的类型为 varchar 50 类型的 x 如何将其更改为 varchar 100 看来我不能啊 你不能 你能做的是 使用 OBJECT DEFINITION 编写包含该类型的所有对象的脚本 放下它们 重新创建具有新长度的类型 重新创建对
  • 在 v21 中设置 AppCompatButton 的样式,使其没有阴影且角半径为零

    我在 XML 布局中定义了一个 AppCompatButton 并为其设置了一个主题 如下所示 android theme style CustomAccentOverlay 我已经设置 android stateListAnimator
  • 为什么“新”运算符使用 -= 来分离事件处理程序?

    为什么我必须使用以下内容来分离事件 object myEvent new MyEvent EventHandler 我有些恼怒new操作员正在工作 有人可以解释一下吗 Update 我已经知道我不必使用 new 运算符来分离事件 但它仍然是
  • 用于自然语言处理的 Java 或 Python [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我想知道哪种编程语言更适合自然语言处理 Java or Python 我发现了很多有关它的问题和答案 但我仍然迷失于选择使用哪一个 我想知道 Java 使用哪个 NLP 库 因为有很多库
  • 如何将 .net 错误消息语言更改为英语

    我使用的是VS2012 net 4 5和Win7专业版 Win7 是土耳其语 现在我收到土耳其语的错误消息 在Win7专业版中无法安装 卸载语言包 是否可以在不重新安装 VS 或 net pack 的情况下更改错误消息语言 这对我有用 开始
  • 通过连接键来展平地图

    给定一个仅包含关键字键的嵌套映射 例如 foo bar 1 baz 2 3 qux quux 4 corge 5 我该如何实施flatten map以便 flatten map foo bar 1 baz 2 3 qux quux 4 co
  • 如何在java中格式化持续时间? (例如格式 H:MM:SS)

    我想使用 H MM SS 等模式来格式化持续时间 以秒为单位 java 中当前的实用程序旨在格式化时间而不是持续时间 如果您不想拖入库 则可以使用格式化程序或相关快捷方式自行完成 例如 给定整数秒数 s String format d 02
  • sizeof 运算符在预处理器 #if 指令中起作用吗?

    我们可以使用sizeof运算符在 if宏 如果是 怎么办 如果没有 为什么 是否sizeof预处理器中的操作员工作 if指令 No the sizeof 运算符在 C 预处理器条件指令中不起作用 例如 if and elif 原因是 C 预
  • 模拟 Guid.NewGuid()

    假设我有以下实体 public class User public int Id get set public string Username get set public Guid UserGuid get set public Guid
  • Laravel 5,查看::分享

    我正在尝试做一个view share current user Auth User 但在 laravel 5 中我找不到在哪里执行此操作 在 L4 中你可以在 baseController 中执行此操作 但那个不再存在 格兰特 格伦 我正在
  • 隐藏表格滚动条

    经过一些研究 我发现我必须设置表格的 tbody display block overflow auto 启用 html 表格上的滚动 是否有可能隐藏每个现代浏览器 Chrome Safari Firefox 上的通用滚动条 我尝试了一些解
  • python请求http响应500(可以在浏览器中访问站点)

    我试图找出我在这里做错了什么 但我总是迷失方向 在 python 2 7 中 我运行以下代码 gt gt gt import requests gt gt gt req requests request GET https www zoma
  • Wix(VS 安装程序)- 缺少编辑器工具栏

    我的电脑上安装了 Wix 3 10 扩展至 Visual Studio 2015 我创建了一个基于 Wix 的安装项目 可以运行 在安装项目中 通常会有一些图标 安装工具 文件系统 注册表 UI 服装操作 但它们目前缺失 您可以在任何 Wi
  • 如何从 Firefox 插件执行 Windows 命令?

    如何使用 Firefox 插件执行 Windows 命令并显示其输出 例如 ping www stackoverfow com 我只是想通过执行打包在一起的二进制文件 或 可执行文件或运行 Windows 命令来探索更多 Firefox 插
  • Delphi、MDI 与多文档界面的选​​项卡

    我正在开发一个多文档应用程序 目前它使用 MDI 这对我 作为开发人员 以及我相信的用户来说都非常方便 然而有一个 反对 我还没有找到解决办法quickly load many到目前为止 子窗口 每次创建窗口并最大化以填充父窗口区域时 都会
  • 安装 Angular CLI 时收到错误警告

    我是这个平台的新手 我安装了Node js但是当我尝试运行命令时npm install g angular cli我收到这个错误 npm WARN deprecated email protected Legacy versions of
  • git checkout 会更新所有文件吗?

    新问题 我想确保我理解这一点 When I git checkout
  • 夏令时和时区最佳实践[关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我希望使这个问题及其答案成为处理夏令时的权威指南 特别是处理实际的转换 如果您有什么要补充的 请做 许多系统都依赖于保持准确的时间 问题在于夏令时导致的时间变化 将时钟向前或向后
  • SQL 更新会在更新运行期间影响其子查询吗?

    我只是编写一个复杂的更新查询 它看起来或多或少像这样 update table join select y min x as MinX from table group by y as t1 using y set x x MinX 这意味