导致 mySQL 服务器实例关闭的 DELETE 语句?

Posted

技术标签:

【中文标题】导致 mySQL 服务器实例关闭的 DELETE 语句?【英文标题】:A DELETE-statement that causes mySQL server instance shutdown? 【发布时间】:2012-05-01 14:35:16 【问题描述】:

通过保存数月的冗余数据,我正在尝试修剪我的数据库。不幸的是,当我运行我认为会删除不必要行的查询时,mysql 服务器实例(不是服务器本身)似乎崩溃了。

DELETE w FROM word w WHERE NOT EXISTS(
    SELECT NULL FROM translation t WHERE t.WordID = w.KeyID LIMIT 1
) AND NOT EXISTS (
    SELECT NULL FROM namespace n WHERE n.IdentifierID = w.KeyID  LIMIT 1
)

有没有办法让这个查询更有效率?

edit #1来自 SQL Workbench 的错误:错误代码:1053。服务器正在关闭

edit #2 下面的查询也失败了,这表明将表格粘合在一起可能有问题?

SELECT w.* FROM word w
    LEFT JOIN translation t ON t.WordID = w.KeyID
    LEFT JOIN namespace n ON n.IdentifierID = w.KeyID
WHERE t.TranslationID IS NULL AND n.NamespaceID IS NULL

在子查询中使用硬编码值是可行的:

SELECT w.* FROM word w WHERE NOT EXISTS(
    SELECT NULL FROM translation t WHERE t.WordID = 1
) AND NOT EXISTS (
    SELECT NULL FROM namespace n WHERE n.IdentifierID = 1
)

edit #3word 包含与表 namespacetranslation表中的每一行相关联的词>。换句话说,word 中的一行可能与 namespacetranslation 表中的一个或多个行相关联。最初认为这是一种防止数据重复和提高搜索性能的方法。

经过数月更新和弃用 namespacetranslation 表中的数据行,有些词不再使用。我想删除这些字词,以便腾出一些空间并提供更相关的搜索结果。

edit #4 我开始认为这可能是超时错误?我尝试将查询更改为以下内容:

DELETE FROM word WHERE KeyID NOT IN (
    SELECT WordID FROM translation 
    UNION
    SELECT IdentifierID FROM namespace
)

没用。

对于索引,解释产生以下结果

id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'PRIMARY', 'word', 'ALL', NULL, NULL, NULL, NULL, '18430', 'Using where'
'2', 'DEPENDENT SUBQUERY', 'translation', 'ALL', NULL, NULL, NULL, NULL, '28219', 'Using where'
'3', 'DEPENDENT UNION', 'namespace', 'ALL', NULL, NULL, NULL, NULL, '7708', 'Using where'
NULL, 'UNION RESULT', '<union2,3>', 'ALL', NULL, NULL, NULL, NULL, NULL, ''

wordKeyID 上的主键和 Key 列上的索引键。

translationTranslationID 上的主键和索引键 NamespaceIDKey

namespaceNamespaceID

上的主键

edit #5 虽然它不一定回答我提出的问题,但以下蛮力查询解决了我的问题。但是,如果数据库有外键,这种方法显然是行不通的,但还是这样:

-- Push all relevant words into a temporary table
CREATE TABLE temp
    SELECT DISTINCT w.* FROM translation t
        INNER JOIN word w ON w.KeyID = t.WordID
    UNION
    SELECT w2.* FROM namespace n2
        INNER JOIN word w2 ON w2.KeyID = n2.IdentifierID;

-- Empty the table
TRUNCATE TABLE word;

-- Re-insert the relevant words
INSERT INTO word            
    SELECT * FROM temp;

【问题讨论】:

如果您在某些行中为子查询硬编码,是否有效? 你想用这个查询做什么?请提供详细信息。 @Dems:我认为问题是 MySQL 正在关闭,而不是整个操作系统。 听起来服务器无论如何都在关闭,我想这是一个红鲱鱼。 @Zanathel - 虽然您已经通过解决问题解决了眼前的问题,但您似乎可能在您的编辑中描述了原因; 您正在加入尚未编制索引的字段。如果您创建以下两个索引,查询可能会显着加快:Translation(WordID)Namespace(IdentifierID)。如果没有这些索引,MySQL 就必须搜索整个表才能找到匹配项。有了索引,MySQL 可以在很短的时间内找到匹配项。如果您在其他任何地方通过这些字段连接这些表,则应该为它们编制索引。 【参考方案1】:

虽然您已经通过解决问题解决了当前的问题,但您似乎已经在您的编辑之一中描述了原因:

您正在加入尚未编制索引的字段。

如果您创建以下两个索引,查询可能会显着加快:

Translation(WordID) Namespace(IdentifierID)

如果没有这些索引,MySQL 将不得不搜索整个表以找到匹配项。有了索引,MySQL 可以在很短的时间内找到匹配项。

如果您在其他任何地方通过这些字段连接这些表,您应该为它们编制索引。

【讨论】:

但是即使列没有被索引,该语句也不应该导致服务器关闭! @a_horse_with_no_name - 我从未真正使用过 MySQL。但是,从一个简短的谷歌来看,如果查询运行时间过长,MySQL 显然有时会关闭并重新启动。如果这是预期的资源管理,我敢打赌它可以配置,但我没有考虑它。现在,我对“如果运行时间过长会出现此错误,并且添加索引意味着它不会运行太久”感到满意。 [处理服务器端命令超时的怪异方式,但 MySQL 无论如何都是怪异的 ;)]【参考方案2】:

错误代码:1053。服务器正在关闭

当与 MySQL 服务器的连接中断时,您会收到此错误。它的文字几乎没有误导性,因为只有连接被关闭,而不是服务器。

例如,我有一个 cron 作业,它会杀死长时间运行的 SELECT 语句以防止服务器过载。当它终止与 mysql KILL 命令的连接时,查询也会返回此错误。

【讨论】:

很高兴知道。谢谢!

以上是关于导致 mySQL 服务器实例关闭的 DELETE 语句?的主要内容,如果未能解决你的问题,请参考以下文章

mysql gh-ost导致自增id重复

直接关闭Linux,导致多实例MySQL无法启动的问题

服务器崩溃导致mysql数据库损坏的数据恢复过程

华为云服务器mysql数据恢复过程

北亚数据库数据恢复使用delete命令未添加where子句删除全表数据的Mysql数据库数据恢复

python 之操作mysql 数据库实例