0

私は巨大なデータベースを持っており、毎日メール トラフィックを処理しています。システムでは、毎日いくつかの古いメールを削除する必要があります。

Delete from EmailList(nolock) 
WHERE EmailId IN ( 
    SELECT EmailId 
    FROM Emails 
    WHERE EmailDate < DATEADD([days], -60, GETDATE())
)

動作しますが、問題は、完了するまでに長い時間がかかり、そのためにログ ファイルが非常に大きくなることです。ログ ファイルのサイズは毎日 100 GB 以上増加します。

に変更できると思います

Delete from EmailList(nolock) 
WHERE EXISTS ( 
    SELECT EmailId 
    FROM Emails 
    WHERE (Emails.EmailId = EmailList.EmailId) AND 
        (EmailDate < DATEADD([days], -60, GETDATE()))
)

しかし、これ以外に、パフォーマンスを改善するためにできることはありますか。何よりも、ログファイルのサイズを減らしますか?

  • EmailId はインデックス化されています。
4

3 に答える 3

0

私は見た

GetDate()-60

スタイル構文は、よりもはるかに優れたパフォーマンスを発揮します

DATEADD([days], -60, GETDATE()))

特に日付列にインデックスがある場合。何人かの仲間の DBA と私は、なぜパフォーマンスが向上するのかを理解しようとかなりの時間を費やしましたが、結果は予想外のものでした。

削除する必要があると思われるレコードの量を考慮して、考慮すべきもう 1 つのことは、たとえば 1000 または 10000 レコードのバッチで削除をチャンクすることです。これにより、おそらく削除プロセスが高速化されます。

于 2012-07-06T19:35:47.787 に答える
0

[編集]:

@TomTom のコメントについて: SQL Server Enterprise エディションを利用できる場合は、 Table Partitioning を使用する必要があります。

そうでない場合は、私の元の投稿が役立つ場合があります。


[元の投稿]

大量のデータを削除することは常に困難です。私は同じ問題に直面し、次の解決策を採用しました。

要件によってはこれは機能しませんが、そこからいくつかのアイデアを得ることができるかもしれません。

1 つのテーブルを使用する代わりに、同じスキーマで2 つのテーブルを使用します。「2つのテーブルのアクティブなテーブル(アクティブな意味、これは現在書き込み中のテーブルです)を指すシノニム(MS SQLサーバーを使用していると仮定します)を作成します。アプリケーションの挿入にこのシノニムを使用するか、またはシノニムを使用する代わりに、アプリケーションは書き込み先の x 日ごとにテーブルを変更するだけで済みます。

x日ごとに、古い/非アクティブなテーブルを切り捨て、その後、切り捨てられたテーブルを対象とするシノニムを再作成できます (シノニム ソリューションを使用する場合)。

アクティブなテーブルの切り替えを同期する必要があります。アプリケーションに共有アプリロックを使用し、シノニムを変更するときに排他的アプリロックを使用して、これを完全に自動化しました (== 切り替えプロセス中に書き込みアプリケーションをブロックします)。

アプリケーションのコードを変更できない場合は、同じ原則を使用することを検討してください。ただし、シノニムに書き込む代わりに、トリガーの代わりにビューを作成できます (挿入操作は「アクティブな」パーティションに挿入されます)。トリガー コードは、上記のように Applock のようなものを使用して syhcnronize する必要があります (切り替えプロセス中の書き込みが機能するように)。

私のソリューションはもう少し複雑なので、現在ここにコードを投稿することはできませんが、負荷の高いアプリケーションでも問題なく動作し、swithcingt/cleanup プロセスは完全に自動化されています。

于 2012-07-06T19:36:15.557 に答える
0

日付による分割を試したことがあれば、もう興味のない日のテーブル バージョンを削除するだけです。「巨大な」データベースを考えると、SQL Server のエンタープライズ エディションを確実に実行し (結局、巨大なデータベースよりも巨大です)、テーブルのパーティション分割が行われます。

于 2012-07-06T20:16:51.270 に答える