2

通过保存数月的冗余数据,我正在尝试修剪我的数据库。不幸的是,当我运行我认为会删除不必要行的查询时,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
)

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

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

编辑#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
)

编辑#3单词包含与表命名空间翻译中的每一行相关联的单词。换句话说, word中的一行可能与命名空间翻译表中的一个或多个行相关联。这是最初被认为是防止数据重复和提高搜索性能的一种手段。

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

编辑#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列上的索引键。

translation : TranslationID上的主键和索引键NamespaceIDKey

namespace : NamespaceID上的主键

编辑#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;
4

2 回答 2

2

尽管您已通过解决直接问题解决了它,但看起来您可能已经在您的编辑之一中描述了原因:

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

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

  • Translation(WordID)
  • Namespace(IdentifierID)

如果没有这些索引,MySQL 就必须搜索整个表才能找到匹配项。有了索引,MySQL 可以在很短的时间内找到匹配项。

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

于 2012-05-01T15:45:27.973 回答
1

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

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

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

于 2015-07-07T13:38:49.817 回答