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
)

このクエリをより効率的にする方法はありますか?

edit #1 SQL Workbench からのエラー: エラー コード: 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表の単語には、テーブルの名前空間翻訳の各行に関連付けられている単語が含まれています。つまり、名前空間変換テーブルの両方の 1 つまたは複数の行に関連付けられている可能性があります。これは本来、データの重複を防ぎ、検索性能を向上させるために考えられた手段です。

名前空間変換テーブルの両方でデータ行の更新と非推奨を数か月にわたって行った結果、使用されなくなった単語があります。これらの単語を削除して、スペースを解放し、より関連性の高い検索結果を提供したいと考えています。

編集#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;
4

2 に答える 2

2

あなたはそれを回避することで当面の問題を解決しましたが、あなたの編集の 1 つで原因を説明したように見えます。

  • インデックスを作成していないフィールドに参加しています。

次の 2 つのインデックスを作成すると、クエリが大幅に高速化される可能性があります。

  • Translation(WordID)
  • Namespace(IdentifierID)

これらのインデックスがないと、MySQL は一致を見つけるためにテーブル全体をトロールする必要があります。インデックスを使用すると、MySQL はわずかな時間で一致を探すことができます。

これらのテーブルを他の場所でこれらのフィールドで結合する場合は、インデックスを作成する必要があります。

于 2012-05-01T15:45:27.973 に答える