1

別のテーブル ('PARENT') への外部キーを持つ必要があるテーブル ('CHILD') から行を選択する必要があるという問題に直面しています。問題は、外部キーが壊れていることです (簡単に言えば、テーブルがパーティション分割されており、何らかの理由で孤立している) ため、外部キーを復元する前に子テーブルをクリーンアップする必要があります。私がやろうとしていることは(大まかに)です:

SELECT child.ID 
from CHILD child 
WHERE child.PARENT_ID NOT IN 
(
  SELECT parent.ID FROM PARENT parent 
);

これは (結果から判断すると) 正しいように見えますが、非常に非効率的です。100 万件の結果があり、子テーブルには 1 億行以上が保持されています。そのクエリの結果から各行を削除する必要があるため、ページネーションを使用していますが、これは NOT IN クエリが毎回繰り返されることを意味します。このため、クエリのパフォーマンスを向上させる方法があるかどうか疑問に思っています。テーブルに参加しようとしましたが、参加する必要があるため機能しないことに気付きましたchild.PARENT_ID = parent.ID。結果はありません。問題は、NOT IN クエリを書き直してパフォーマンスを向上させる方法はないかということです。

4

3 に答える 3

0

通常、この構文は非常に効率的です。

select id from child
where
    parent_id in
    (
        select parent_id from child
        minus
        select id from parent
    );

ここで、子行を削除しようとすると、非常に遅くなります。

代わりに、保持したい子レコードの新しいテーブルを作成してから、古い子テーブルの名前を変更または削除し (最初にバックアップを取ってください)、新しい子テーブルの名前を子に変更する方が迅速です。

次に、主キーと外部キーの制約を作成すると、リンクが壊れることはなくなります。

また、ページネーションについて言及していることも心配です。何を言っているのかわかりませんが、何百万行も実行できない手動のように聞こえます。

于 2017-12-28T10:06:12.620 に答える