web-dev-qa-db-ja.com

大きなテーブルのすべてのデータを削除する最も速い方法

約500万行を含むログテーブルからすべての行を削除する必要がありました。私の最初の試みは、クエリアナライザーで次のコマンドを発行することでした。

client_logから削除

非常に長い時間がかかりました。

44
Ron Skufca

テーブルの切り捨て を確認してください。これは非常に高速です。

76
Rob Walker

Msdn transact-SQLリファレンスでTRUNCATE TABLEを発見しました。ここに興味があるすべての人のために発言があります:

TRUNCATE TABLEは、WHERE句のないDELETEステートメントと機能的に同じです。両方ともテーブル内のすべての行を削除します。ただし、TRUNCATE TABLEはDELETEよりも高速で、使用するシステムおよびトランザクションログリソースが少なくなります。

DELETEステートメントは、一度に1行ずつ削除し、削除された各行のトランザクションログにエントリを記録します。 TRUNCATE TABLEは、テーブルのデータを格納するために使用されるデータページの割り当てを解除することでデータを削除し、ページの割り当て解除のみがトランザクションログに記録されます。

TRUNCATE TABLEはテーブルからすべての行を削除しますが、テーブル構造とその列、制約、インデックスなどは残ります。新しい行のIDが使用するカウンターは、列のシードにリセットされます。 IDカウンターを保持する場合は、代わりにDELETEを使用します。テーブル定義とそのデータを削除する場合は、DROP TABLEステートメントを使用します。

FOREIGN KEY制約によって参照されるテーブルではTRUNCATE TABLEを使用できません。代わりに、WHERE句なしでDELETEステートメントを使用します。 TRUNCATE TABLEは記録されないため、トリガーをアクティブにできません。

TRUNCATE TABLEは、イン​​デックス付きビューに参加しているテーブルでは使用できません。

33
Ron Skufca

TRUNCATEが何らかの形でトランザクションログをスキップするという一般的な神話があります。

これは誤解であり、MSDNで明確に言及されています。

この神話は、ここでいくつかのコメントで呼び出されます。一緒に根絶しましょう;)

15
squadette

参考のために TRUNCATE TABLE はMySQLでも動作します

6
UnkwnTech

切り捨てを忘れて削除します。テーブル定義を維持し(再作成する場合)、ドロップテーブルを使用します。

3
siculars

次の方法を使用してテーブルをゼロにしますが、テーブルのアーカイブコピーが残されるという追加のボーナスがあります。

CREATE TABLE `new_table` LIKE `table`;
RENAME TABLE `table` TO `old_table`, `new_table` TO `table`;
3
dar7yl

SQL Serverでは、Truncate Tableコマンドを使用できます。これは、通常の削除よりも高速で、使用するリソースも少なくなります。 IDフィールドもリセットされ、シード値に戻ります。

Truncateの欠点は、外部キーによって参照されるテーブルでは使用できず、トリガーを起動しないことです。また、何か問題が発生した場合は、データをロールバックできません。

1
Martynnw

truncate tablenot SQLプラットフォームに依存しません。 mightがデータベースプロバイダーを変更すると思われる場合は、それを使用することに注意してください。

1
James A. Rosen

TRUNCATEを使用している場合、自動インクリメントキーもリセットされることに注意してください。

自動インクリメントキーを失いたくない場合は、セットで削除することで削除を高速化できます(たとえば、DELETE FROM table WHERE id> 1 AND id <10000)。大幅に高速化され、場合によってはデータのロックアップが防止されます。

1
Brian D.

「テーブルを削除して再作成する」という提案は、おそらく外部キーを破壊するため、良いものではありません。

外部キーを使用していますか?

0
Andy Lester

はい、まあ、500万行の削除にはおそらく時間がかかるでしょう。私が考えることができる唯一の潜在的に高速な方法は、テーブルを削除し、それを再作成することです。もちろん、テーブル内のすべてのデータを削除する場合にのみ機能します。

0
TheSmurf

テーブルclient_logを切り捨てる

最善の方法は、truncateがテーブルとインデックスのすべてのコンテンツを削除し、取得したシードをリセットすることです。

0
Ronald Hobbs

私は以前の声明を改訂しています:

TRUNCATEを使用すると、データは消去されますが、トランザクションログには何も記録されないことを理解する必要があります。ログへの書き込みが、DELETEが500万行を永久に使用する理由です。開発中にTRUNCATEを頻繁に使用しますが、変更をロールバックできないため、運用データベースでTRUNCATEを使用する場合は注意が必要です。 TRUNCATEを実行した後、すぐにデータベースの完全バックアップを作成して、復元の新しい基盤を確立する必要があります。

上記の説明は、両者に違いがあることを確実に理解するように促すことを目的としています。残念ながら、2つの間で実際にテストを行っていないため、記述が不十分で、サポートされていないステートメントを作成します。他の人から聞いた声明に基づいています。

[〜#〜] msdn [〜#〜] から:

DELETEステートメントは、一度に1行ずつ削除し、削除された各行のトランザクションログにエントリを記録します。 TRUNCATE TABLEは、テーブルのデータを格納するために使用されるデータページの割り当てを解除することでデータを削除し、ページの割り当て解除のみがトランザクションログに記録されます。

2つの間に根本的な違いがあり、違いがあるため、どちらか一方が不適切である可能性のあるアプリケーションがあると言いたいだけです。

0
Andy Frieders

外部キーやトリガーのためにTRUNCATE TABLEを使用できない場合は、次のことを検討できます。

  • すべてのインデックスを削除します。
  • 通常のDELETEを実行します。
  • すべてのインデックスを再作成します。

これにより、DELETEが多少高速化される場合があります。

0
squadette