当前位置: 首页 > 知识库问答 >
问题:

mysql - 在MySQL中,用update join,里面有order by,会导致MySQL崩溃吗?

高高雅
2023-10-10

我现在有两个SQL文,第一个可以正常执行,第二个一执行MySQL就崩溃。。
崩溃指的是:docker里面对应的那个MySQL容器直接没了,docker ps -a都看不到的那种。

第一个SQL文:
update    cfg_dev_network_push_status as T1inner join cfg_dev_network_bind_status as T2 on    T1.task_id = T2.id    and T1.del_flag = '0'    and T1.push_type = '1'    and T1.push_result != '0'    and T1.push_retry_times < 3    and T2.del_flag = '0'    and T2.dev_id = 'theDevId'    and T2.status = '1' set    T1.push_retry_times = T1.push_retry_times + 1,    T1.push_status = '1',    T1.push_end_time = '20231010141154002',    T1.push_result = '1',    T1.fail_reason = '109'order by    T1.id asc
第二个SQL文:
update    cfg_dev_network_push_status as T1inner join cfg_dev_network_bind_status as T2 on    T1.task_id = T2.id    and T1.del_flag = '0'    and T1.push_type = '1'    and T1.push_result != '0'    and T1.push_retry_times < 3    and T2.del_flag = '0'    and T2.dev_id = 'theDevId'    and T2.status = '1' set    T1.push_retry_times = T1.push_retry_times + 1,    T1.push_status = '1',    T1.push_end_time = '20231010141154002',    T1.push_result = '1',    T1.fail_reason = '109'order by    T1.push_status desc,    T1.push_retry_times desc,    T1.id asc

经测试,第二个SQL文里面,T1.push_status descT1.push_retry_times desc,加任意一个,都会导致MySQL崩溃,只有T1.id asc的时候,是可以正常执行的。
push_status的数据类型是char(1),数据里面非0即1。
push_retry_times的数据类型是int。

数据库中两个表的数据都在50条左右,不存在内存过大的影响;
直接在DBeaver中进行数据查询,不考虑锁的影响。

之后我在服务器中没找到MySQL相关崩溃的日志。。。。

所以,为啥会崩呗,求各路大神帮助~

共有1个答案

红存
2023-10-10

在MySQL中,使用UPDATE JOIN语句时,ORDER BY子句可能会导致性能问题,尤其当涉及到的表数据量较大时。这是因为ORDER BY会对所有更新的行进行排序,而不仅仅是对影响行进行排序。

在你的第二个SQL语句中,你使用了多个排序条件(T1.push_status descT1.push_retry_times descT1.id asc)。这会增加排序操作的复杂性,并可能导致MySQL在处理时遇到困难。尤其当push_statuspush_retry_times的数据类型是char(1)和int时,可能由于数据的特性导致排序操作出现问题。

另外,MySQL对于使用ORDER BYUPDATEDELETE语句有一些限制。当涉及到大量数据时,可能会因为内存不足而崩溃。

如果你需要进行排序,你可以考虑以下几种解决方案:

  1. 先进行排序,再进行更新:首先,使用相同的WHERE条件对表进行排序,并将结果存储在一个临时表中。然后,使用该临时表进行更新操作。
CREATE TEMPORARY TABLE TempTable ASSELECT * FROM cfg_dev_network_push_status WHERE push_result != '0' AND push_retry_times < 3 AND del_flag = '0' AND push_type = '1' AND dev_id = 'theDevId' AND status = '1' ORDER BY push_status DESC, push_retry_times DESC, id ASC;UPDATE cfg_dev_network_push_status as T1 INNER JOIN cfg_dev_network_bind_status as T2 ON T1.task_id = T2.id SET T1.push_retry_times = T1.push_retry_times + 1, T1.push_status = '1', T1.push_end_time = '20231010141154002', T1.push_result = '1', T1.fail_reason = '109' WHERE T1.id IN (SELECT id FROM TempTable);
  1. 使用脚本或程序进行更新:如果你有访问数据库服务器的脚本或程序,你可以考虑通过脚本或程序来进行更新操作。这样可以避免直接在数据库中执行可能存在问题的SQL语句。
  2. 考虑数据库设计:如果这些更新操作经常需要进行,考虑修改数据库设计,创建一个字段或表来跟踪需要更新的行。这样可以避免直接使用ORDER BY进行更新的需求。
  3. 升级MySQL版本:一些旧版本的MySQL可能在处理某些操作时存在问题。考虑升级到最新稳定版本,看是否解决问题。
  4. 增加内存限制:如果数据库服务器有足够的资源,你可以考虑增加MySQL的内存限制。这可以通过调整MySQL配置文件(如my.cnf)中的相关参数来实现。但是,这并不是一个长期解决方案,因为如果你的数据量非常大,增加内存限制可能只是延迟了崩溃的时间。

综上所述,最理想的解决方案可能是首先对数据进行排序,然后进行更新操作。这样可以避免直接在MySQL中使用ORDER BY的更新语句,可能导致的性能问题或崩溃。

 类似资料:
  • 我在< code>Ubuntu 14.04服务器上有以下< code>PHP 5.6.19代码。这段代码简单地连接到一个< code>MySQL 5.6.28数据库,等待一分钟,启动自己的另一个进程,然后退出。 注意:这是完整的脚本,其目的是演示问题-它没有做任何有用的事情。 我使用 是失败的那一行,因为我通过在脚本中的某些点记录到一个文件中做了进一步的调试(上面没有显示)。

  • 问题内容: 当我选择2个条件时,mysql总是崩溃。对我来说,这个问题很奇怪: 就是为了这张桌子 这只发生在我的笔记本上。我们有具有相同版本mysql和相同sql的测试服务器(linux)可以 仅在任何一种情况下都不会发生 我尝试删除并重新创建表,转储数据,问题仍然存在 我尝试重新安装相同版本的mysql,并在笔记本中再次发生 有人说mysql 5.6可以,我没有尝试 Mysql版本是5.7.17

  • 我有一个discord bot,我正在处理一个命令,该命令从mysql数据库中显示关于一个字符的信息(通过提供字符名)。它工作得很好,但如果我提供了一个数据库中不存在的名称,如,则bot会崩溃。所以我的问题是。希望你能理解我的意思。 代码如下: 如果你需要我提供你更多的信息,让我知道。 感谢任何帮助!

  • 我正在尝试使用、和(不使用)实现实时相机应用程序 所以,我发现这篇教程 http://altitudelabs.com/blog/real-time-filter/ 它是用Objective-C编写的,所以我在Swift4.0中重写了那个代码,xcode9 它看起来工作很好,但有时(很少),它崩溃了以下错误。调用的方法时 EXC_BAD_ACCESS(代码=1,地址+0x************)

  • 我正在使用mariadb和wordpress容器。但是这个错误一直在发生。我如何确保这种崩溃不再发生?我被攻击了吗?或者是发生在其他人身上的问题?我怎样才能连接到mariadb,并访问shell,并试图找出mariadb容器中发生了什么? 请看下面每次崩溃后记录的消息...页面点击量似乎也很高。页面访问量高达20,000到60,000次点击。这些似乎是爬虫,机器人的工作。不确定这些是不是恶意攻击。

  • 我试图用LWJGL编写一个opengl渲染器。为了打开窗户,我用的是GLFW。但是,当我调用glfwCreateWindow时,它会崩溃,出现以下错误: Java运行时环境检测到一个致命错误: 谢了!