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