cats
42,795,120 行のテーブルがあります。
どうやらこれは行数が多いようです。だから私がするとき:
/* owner_cats is a many-to-many join table */
DELETE FROM cats
WHERE cats.id_cat IN (
SELECT owner_cats.id_cat FROM owner_cats
WHERE owner_cats.id_owner = 1)
クエリがタイムアウトします:(
(編集: 値を増やす必要があり CommandTimeout
ます。デフォルトはわずか 30 秒です)
TRUNCATE TABLE cats
他の飼い主から猫を吹き飛ばしたくないので使えません。
「リカバリ モデル」を「シンプル」に設定して SQL Server 2005 を使用しています。
だから、私はこのようなことをすることを考えました(ところでアプリケーションからこのSQLを実行します):
DELETE TOP (25) PERCENT FROM cats
WHERE cats.id_cat IN (
SELECT owner_cats.id_cat FROM owner_cats
WHERE owner_cats.id_owner = 1)
DELETE TOP(50) PERCENT FROM cats
WHERE cats.id_cat IN (
SELECT owner_cats.id_cat FROM owner_cats
WHERE owner_cats.id_owner = 1)
DELETE FROM cats
WHERE cats.id_cat IN (
SELECT owner_cats.id_cat FROM owner_cats
WHERE owner_cats.id_owner = 1)
私の質問はDELETE
、SQL Server 2005 で使用できる行数のしきい値はどれくらいですか?
または、私のアプローチが最適でない場合は、より良いアプローチを提案してください。ありがとう。
この投稿は私を十分に助けませんでした:
編集 (2010 年 8 月 6 日):
さて、上記のリンクをもう一度読んだ後、これらのテーブルにインデックスがないことに気付きました。また、以下のコメントですでにその問題を指摘している人もいます。これは架空のスキーマでid_cat
あり、PK ではないことに注意してください。実際のスキーマでは、一意のフィールドではないためです。
インデックスを配置します:
cats.id_cat
owner_cats.id_cat
owner_cats.id_owner
私はまだこのデータ ウェアハウジングのコツをつかんでいると思います。明らかに、すべてのJOIN
フィールドにインデックスが必要ですよね?
ただし、このバッチ ロード プロセスを実行するには数時間かかります。私はすでにそれをSqlBulkCopy
(一度に42ミルではなく、チャンクで)やっています。いくつかのインデックスと PK があります。次の投稿を読んで、インデックスが一括コピーでも遅くなるという私の理論を確認しました。
そのためDROP
、コピーの前にインデックスに移動し、コピーが完了したら再度インデックスを作成しますCREATE
。
ロード時間が長いため、これらの提案をテストするにはしばらく時間がかかります。結果とともにまた報告します。
更新 (2010 年 8 月 7 日):
トムは次のように提案しました。
DELETE
FROM cats c
WHERE EXISTS (SELECT 1
FROM owner_cats o
WHERE o.id_cat = c.id_cat
AND o.id_owner = 1)
それでもインデックスがない場合、4,200 万行の場合、上記の方法では 22:08 に対して 13:21 分: 秒かかりました。ただし、1,300 万行の場合、私の古い方法では 2:10 に対して 2:13 かかりました。これは素晴らしいアイデアですが、それでもインデックスを使用する必要があります。
更新 (2010 年 8 月 8 日):
何かがひどく間違っています!インデックスをオンにすると、上記の最初の削除クエリは 1:9 時間:分(はい、1 時間です!)対 22:08 分:秒および 13:21 分:秒対 2:10 分:秒で 4,200 万行とそれぞれ13ミリ行。インデックスを使って Tom のクエリを試してみますが、これは間違った方向に向かっています。助けてください。
更新 (2010 年 8 月 9 日):
Tom の削除には、42 万行の場合は 1:06 時間:分、1,300 万行の場合は 10:50 分:秒かかりましたが、それぞれ 13:21 分:秒と 2:13 分:秒でした。 桁違いにインデックスを使用すると、データベースの削除に時間がかかります! 私のデータベースの .mdf と .ldf が、最初の (42 ミル) の削除中に 3.5 GB から 40.6 GB に増加した理由はわかっていると思います。 私は何を間違っていますか?
更新 (2010 年 8 月 10 日):
他のオプションがないため、私は、うまくいかない解決策であると感じているものを思いつきました(できれば一時的なものです):
- データベース接続のタイムアウトを 1 時間に増やします (
CommandTimeout=60000;
デフォルトは 30 秒) 。 - トムのクエリを使用:
DELETE FROM WHERE EXISTS (SELECT 1 ...)
少し高速に実行されたため DROP
削除ステートメントを実行する前のすべてのインデックスと PK (???)- 実行
DELETE
ステートメント CREATE
すべてのインデックスと PK
クレイジーに思えますが、少なくとも最初のロードを使用してTRUNCATE
最初からやり直すよりも高速です. 4200万行。(注: ロード プロセスが例外をスローした場合、最初からやり直しますが、以前の を吹き飛ばしたくないので、テーブルを使用したくないため、 を使用しようとしています。)owner_id
owner_id
owner_id
owner_id
TRUNCATE
owner_cats
DELETE
もう助けていただければ幸いです:)