約 500 万行を含むログ テーブルからすべての行を削除する必要がありました。私の最初の試みは、クエリ アナライザーで次のコマンドを発行することでした。
client_log から削除
これには非常に長い時間がかかりました。
約 500 万行を含むログ テーブルからすべての行を削除する必要がありました。私の最初の試みは、クエリ アナライザーで次のコマンドを発行することでした。
client_log から削除
これには非常に長い時間がかかりました。
はるかに高速な切り捨てテーブルを確認してください。
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 は、インデックス付きビューに参加しているテーブルでは使用できません。
TRUNCATEはどういうわけかトランザクションログをスキップするという一般的な神話があります。
これは誤解であり、MSDNで明確に言及されています。
この神話は、ここのいくつかのコメントで呼び出されます。一緒に根絶しましょう;)
参考までにTRUNCATE TABLEは MySQL でも動作します
次の方法を使用してテーブルをゼロにしますが、テーブルのアーカイブコピーが残るという追加のボーナスがあります。
CREATE TABLE `new_table` LIKE `table`;
RENAME TABLE `table` TO `old_table`, `new_table` TO `table`;
切り捨てと削除を忘れてください。テーブル定義を維持し (再作成する場合)、drop table を使用するだけです。
テーブル client_log を切り捨てます
truncate は、テーブルとインデックスのすべてのコンテンツを削除し、持っているシードもリセットします。
SQL Server ではTruncate Table
、通常の削除よりも高速で、使用するリソースも少ないコマンドを使用できます。ID フィールドもシード値にリセットされます。
切り捨ての欠点は、外部キーによって参照されるテーブルでは使用できず、トリガーを起動しないことです。また、何か問題が発生した場合、データをロールバックすることはできません。
truncate table
SQL プラットフォームに依存しません。データベース プロバイダーを変更する可能性があると思われる場合は、その使用に慎重になる可能性があります。
自動増分キーを使用している場合、TRUNCATE は自動増分キーもリセットすることに注意してください。
自動増分キーを失いたくない場合は、セットで削除することで削除を高速化できます (例: DELETE FROM table WHERE id > 1 AND id < 10000)。大幅に高速化され、場合によってはデータがロックされるのを防ぐことができます。
はい、まあ、500 万行を削除するには、おそらく長い時間がかかります。私が考えることができる唯一の潜在的に高速な方法は、テーブルを削除して再作成することです。もちろん、テーブル内のすべてのデータを削除したい場合にのみ機能します。
「テーブルを削除して再作成する」という提案は、おそらく適切ではありません。
あなたは外部キーを使用していますよね?
私は以前の声明を修正しています:
TRUNCATE を使用すると、データは消去されますが、トランザクション ログには何も記録されないことを理解しておく必要があります。ログへの書き込みは、DELETE が 500 万行で永遠にかかる理由です。開発中に TRUNCATE をよく使用しますが、変更をロールバックできないため、運用データベースで使用する場合は注意が必要です。TRUNCATE を実行した後、すぐに完全なデータベース バックアップを作成して、復元の新しい基盤を確立する必要があります。
上記のステートメントは、この 2 つの間に違いがあることを確実に理解するよう促すことを目的としています。残念ながら、私は実際に 2 つの間でテストを行っていないため、記述が不十分であり、サポートされていないステートメントを作成しています。他の人から聞いた話に基づいています。
MSDNから:
DELETE ステートメントは、行を 1 つずつ削除し、削除された行ごとにトランザクション ログにエントリを記録します。TRUNCATE TABLE は、テーブルのデータを格納するために使用されるデータ ページの割り当てを解除することによってデータを削除します。ページの割り当て解除のみがトランザクション ログに記録されます。
両者には根本的な違いがあり、違いがあるため、どちらか一方が不適切なアプリケーションが存在することを言いたかっただけです。
外部キーやトリガーが原因で TRUNCATE TABLE を使用できない場合は、次のことを検討できます。
これにより、DELETE がいくらか高速化される場合があります。
DELETE * FROM table_name;
時期尚早の最適化は危険です。最適化とは奇妙なことをすることを意味するかもしれませんが、それが機能する場合は、それを利用したいと思うかもしれません。
SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;
速度については、依存すると思います...
基盤となるデータベース: Oracle、Microsoft、MySQL、PostgreSQL、その他、カスタム...
表、その内容、および関連する表:
削除ルールがある場合があります。テーブル内のすべてのコンテンツを削除する既存の手順はありますか? これは、特定の基盤となるデータベース エンジン用に最適化できますか? 物事や関連データを壊すことについて、私たちはどれくらい気を配っていますか? 関連する他のテーブルがこのテーブルに依存していないと仮定すると、DELETE を実行するのが「最も安全な」方法かもしれません。このテーブル内のデータに関連する/依存する他のテーブルやクエリはありますか? このテーブルが存在することをあまり気にしない場合は、基礎となるデータベースによっては、DROP を使用するのが高速な方法かもしれません。
DROP TABLE table_name;
何行が削除されていますか? 削除を最適化するために迅速に収集される他の情報はありますか? たとえば、テーブルがすでに空かどうかを判断できますか? 数百、数千、数百万、数十億の行があるかどうかわかりますか?