0

2,000 万件近くのレコードがあり、増え続けているテーブルがあります。テーブルは innodb としてセットアップされました。2 つの主要なフィールドにプライマリ インデックスがあります。

`entries_to_fields`
entry_id    int(11) NO  PRI NULL     
field_id    int(11) NO  PRI NULL     
value   text    NO      NULL     

レコードの数にもかかわらず、このテーブルへのほとんどのクエリは、次の例外を除いて非常に高速です。

DELETE FROM `entries_to_fields` WHERE `entry_id` IN (SELECT `id` FROM `entries` WHERE `form_id` = 196)

これにより、特定のフォームのすべての入力データが削除されます。

現在、エントリ テーブルが結果を返さない場合でも、これには 45 秒以上かかります。

私の質問は、構造に簡単な変更をentries_to_fields加えることができるか、またはクエリをさらに最適化できるかということです。

4

3 に答える 3

3

私はあなたの答えを読んだ後、あなたにも役立つかもしれないこのクエリを書きました(将来)。

DELETE entries_to_fields
FROM entries_to_fields
JOIN entries
ON entries_to_fields.entry_id = entries.id
WHERE entries.form_id = 196

...entries.form_idフィールドにインデックスを付ける必要があります。

于 2011-08-02T06:23:30.443 に答える
1

クエリプランを見ると、サブクエリがNULLを返し、削除をフルスキャンしていると思います。

見る :

http://dev.mysql.com/doc/refman/5.0/en/in-subquery-optimization.html

于 2011-08-02T06:27:24.143 に答える
1

少しの試行錯誤とグーグル検索の後、IN大きなテーブルでインデックス フィールドを使用することは非常に悪い習慣であることがわかりました。

サブクエリを別のクエリに分割し、次のように動的クエリを作成しました。

DELETE FROM `entries_to_fields` WHERE `entry_id` = 232 OR `entry_id` = 342 ...

大規模なクエリが生成される可能性がありますが、現在は 1 秒以内に実行されます。何千ものエントリを削除する場合でも。

于 2011-08-02T06:15:46.820 に答える