2009-12-07 8 views
25

テーブルに行があります。この行には、数百万行の他のいくつかのテーブルで参照されるID列があります。行を削除するSQL文は、常にタイムアウトします。私のデザインから、私が削除したい行が他のどこにも参照されないことがわかっています。したがって、私はSQLに、この行への外部キー参照のために他のすべてのテーブルをチェックしてすぐに行を削除することを無視するようにしたいと思います。 SQL 2008でこれを行う簡単な方法はありますか?おそらく、 の線に沿って何か:これらの線に沿ってすべての外部キーと制約を無視してSQL行を削除する

DELETE FROM myTable where myTable.ID = 6850 IGNORE CONSTRAINTS 

か何か。

+3

関連テーブルのキー参照列にインデックスを追加することを検討しましたか?まだ存在しない場合は、これにより、SQLが他の行が削除しようとしている行を参照しているかどうかを迅速に判断することができ、実質的なパフォーマンスの向上をもたらす可能性があります。 –

+0

別のアプローチを提案できます。私のシステムでは、ほとんどの(何百もの)テーブルがdbo.Company.Idを指しています。空の会社を削除しても参照がなくても、DBは数十億行のFKの整合性をチェックします。解決方法:論理的な削除だけを使用してください。 – jean

答えて

30

一時的にチェックしないようにそのテーブル/列に制約を設定してから、再度制約を有効にすることができます。一般的な形式は次のようになります。

ALTER TABLE TableName NOCHECK CONSTRAINT ConstraintName 

ALTER TABLE TableName CHECK CONSTRAINT ConstraintName 

とその後再度有効にするすべての制約私は、これはしかし、一時的であろうと仮定しますか?あなたは明らかにこれを一貫してしたく​​ないでしょう。

1

、使用を:

ALTER TABLE MyOtherTable NOCHECK CONSTRAINT fk_name 
17

はい、単に

を実行します
DELETE FROM myTable where myTable.ID = 6850 

とLET ENGINE CONSトレーニング

制約を無効にして無効にしようとすると、拘束を有効にすると、削除したばかりの行の代わりにの行がすべてであることを確認する必要があります。 SQLには、制約が「信頼できる」かどうかを知るための内部フラグがあります。あなたは '最適化'を行うと、これらのフラグを「偽」に変更するか(SQLはもはや制約を信頼しないことを意味する)、ゼロから再検証する必要があります。

Guidelines for Disabling Indexes and ConstraintsおよびNon-trusted constraints and performanceを参照してください。

DELETE操作の制約検証がパフォーマンスのボトルネックであることを実証した測定値の実測値を除き、エンジンにその作業をさせてください。

+1

いくつかの実際の数値を取得するだけです:12Mテーブルから10Mレコードを削除することは、1つの一時的に非アクティブ化された制約を有効にした場合(12:18対10:28) - SQL-Server – Remco

+1

場合によっては、 DB上にドメインテーブルを作成するのと同じように、FKチェックを無効にする必要があります。誰かが何らかの理由で誤ったコード値を持つルックアップアイテムを追加した場合、そのアイテムを削除して正しいコードとテキスト値。 – ProfK

7

いかなる場合でも制約を無効にしないでください。これは非常にばかげた練習です。このようなことをすれば、データの整合性を維持することはできません。データの整合性は、データベースがなければ何も持たないため、データベースの第一の考慮事項です。

正しい方法は、親レコードを削除する前に子テーブルから削除することです。カスケードデルタを設定しているため、おそらくタイムアウトしている可能性があります。これは、大規模なデータベースでは別の悪い習慣です。

+6

これは、あなたが何をしているのかを本当に知っている特定の状況で、トランザクションの最後にすべての制約が満たされていることを確認するのに非常に役立ちます。たとえば、SqlBulkCopyは既定で制約を無視しますが、これについて考えると意味があります。 – chris

+1

@chris、キーフレーズはあなたがしていることを本当に知っています。一般的に、これらの人々は、インターネット上の制約を無効にする方法を求めていません。 – HLGEM

1

すべてのレコードがすべてのテストデータであるため、両方のテーブルからすべてのレコードを削除したかったのです。私はSSMS GUIを使用してFK制約を一時的に無効にしてから、両方のテーブルでDELETEクエリを実行し、最後にFK制約を再度有効にしました。FK制約を無効にするには

  1. は、データベースオブジェクトを展開[1]
  2. は、従属テーブルオブジェクトを展開し、[2]
  3. に 'キー' フォルダ
  4. 右クリックして拡大外部キー
  5. '変更'オプションを選択
  6. '外部キー制約を強制する'オプションを 'いいえ'に変更する
  7. プロンプトが表示され、確認が変化
  8. 実行に必要な削除クエリ
  9. 再度有効に外部キー制約にあなたがそれを無効にし、同じように保存するとき
  10. 「外部キー関係」ウィンドウを閉じるには、
  11. テーブルデザイナー]タブを閉じます。

[1]「オブジェクトエクスプローラ」ペインで、「表示」メニューオプション、またはキーF8を介してアクセスすることができ

[2]あなたが依存一つであるテーブルわからない場合問題のテーブルを右クリックし、[依存関係の表示]オプションを選択することで確認できます。

+0

オブジェクトエクスプローラでテーブルを削除し、バッチを再作成するほうが簡単です(FK制約のため削除できなかったテーブルの削除を再度実行してください)。 – appl3r

1

私はこれが古いスレッドだと知っていますが、私の行削除が外部キー制約によってブロックされたときに私はここに着いた。私の場合、私のテーブルデザインでは、制約付きの列に "NULL"値が許されていました。削除する行では、制約付き列の値を「NULL」(外部キー制約に違反しない)に変更し、すべての行を削除しました。

関連する問題