【发布时间】: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 #3 表 word 包含与表 namespace 和 translation表中的每一行相关联的词>。换句话说,word 中的一行可能与 namespace 和 translation 表中的一个或多个行相关联。最初认为这是一种防止数据重复和提高搜索性能的方法。
经过数月更新和弃用 namespace 和 translation 表中的数据行,有些词不再使用。我想删除这些字词,以便腾出一些空间并提供更相关的搜索结果。
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, ''
word:KeyID 上的主键和 Key 列上的索引键。
translation:TranslationID 上的主键和索引键 NamespaceIDKey
namespace:NamespaceID
上的主键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 可以在很短的时间内找到匹配项。如果您在其他任何地方通过这些字段连接这些表,则应该为它们编制索引。
标签: mysql sql mysql-workbench