3

food と moos の 2 つのテーブルがあります。

  • foos は start_date に索引付けされます
  • moos は外部キーとして foos.id を持っています

foos は非常に大きい (数百万レコード)。moos ではありません (100k レコード)。

かなり単純なことをする必要があります: start_date < X で、moos で参照されていないレコードを foos から削除します。あまり具体的な質問ではないことを願っていますが、機能させることができません(永遠にハングします)「通常の」方法だと思うことを試しました:

delete foos FROM foos LEFT JOIN moos ON foos.id = moos.foo_id WHERE moos.foo_id is null AND foos.start_date < "2013-05-30";

delete foos FROM foos WHERE start_date < "2013-05-30" AND id NOT IN (select foo_id from moos where foo_id is not null);

追加する必要があります:

  • start_date < X が大きくない (<> 200/300k レコード) の moos の数を知るために、常に X を選択します。

  • foo を参照する moos は数千しかありません

  • 私はmySQL 5.5を使用しているため、「削除」を説明することはできませんが、「select 1」に置き換えると、説明はmySQLが私が思っていたことを実行していることを示唆しています:

    • 最初に start_date インデックスを使用して適切な foos を見つけます
    • それから moos を見て、そんなに「長い」トランザクションにならないように…</li>

これを行うためのより良い方法はありますか、それとも何か不足していますか?

ありがとう、

PJ

4

4 に答える 4

0

foo_id の Moos テーブルにインデックスを追加することになり、問題は解決しました。なぜ正直に言う必要があるのか​​ わかりません(Moosは大きなテーブルではないことを考えると)...

時間を割いて助けてくれてありがとう。

PJ

于 2013-06-05T09:56:43.460 に答える
0

どうですか...

CREATE TABLE foos_new
SELECT *
FROM
    foos
LEFT JOIN moos on foos.id = moos.foo_id
WHERE
    moos.foo_id IS NOT NULL
    OR
    (
        moos.foo_id IS NULL AND
        foos.start_date >= "2013-05-30"
    );

次に、元のテーブルを削除し、新しいテーブルの名前を foos に変更します。さらに、もちろんインデックスを追加します。

于 2013-05-31T11:47:53.610 に答える