書き込みが多い製品のデータベースがあります。SSDを備えた新しいサーバーマシンを購入しました。驚いたことに、挿入ははるかに遅いストレージを備えた古いマシンよりも高速ではありませんでした。ベンチマーク中に、SQL Serverプロセスが示すIOレートが非常に低いことがわかりました。
たとえば、ループの周りにBEGIN TRANとCOMMITを追加したことを除いて、このページにあるスクリプトを実行しました。せいぜい、ディスク使用量が7Mb / sに達するのを見ることができましたが、CPUはほとんど5%に触れませんでした。サーバーには64Gbがインストールされており、10を使用しています。合計実行時間は、最初の呼び出しでは2分15秒、その後の呼び出しでは約1分でした。データベースは単純なリカバリであり、テスト中はアイドル状態でした。各呼び出しの間にテーブルを削除しました。
なぜこのような単純なスクリプトがそんなに遅いのですか?ハードウェアはほとんど使用されていません。専用ディスクベンチマークツールとSQLIOの両方は、読み取りと書き込みの両方でSSDが500Mb / s以上の速度で正しく実行されることを示しています。ランダム書き込みはシーケンシャル書き込みよりも遅いことを理解していますが、クラスター化インデックスを持たないテーブルへのこのような単純な挿入は、はるかに高速になると予想されます。
最終的に、このシナリオははるかに複雑ですが、最初に単純なケースを理解する必要があると感じています。簡単に言うと、アプリケーションは古いデータを削除し、SqlBulkCopyを使用して新しいデータをステージングテーブルにコピーし、フィルター処理を実行し、最後にMERGEおよび/またはINSERT INTOを使用してデータを最終テーブルにコピーします。
->編集1:Martin Smithによってリンクされた手順に従い、次の結果が得られました。
[Wait Type] [Wait Count] [Total Wait (ms)] [T. Resource Wait (ms)] [T. Signal Wait (ms)]
NETWORK_IO 5008 46735 46587 148
LOGBUFFER 901 5994 5977 17
PAGELATCH_UP 40 866 865 1
SOS_SCHEDULER_YIELD 53279 219 121 98
WRITELOG 5 145 145 0
PAGEIOLATCH_UP 4 58 58 0
LATCH_SH 5 0 0 0
表示する結果がなく、SQLファイル以外に転送するデータがないことを考えると、NETWORK_IOにはほとんど時間がかかります。NETWORK_IOタイプにはすべてのIOが含まれますか?
->編集2:20Gb RAMディスクを作成し、そこからデータベースをマウントしました。SSDでの最高の時間は48秒でしたが、RAMディスクでは37秒になりました。NETWORK_IOは依然として最大の待機時間です。RAMディスクへの最大書き込み速度は約250Mb / sでしたが、1秒あたり数ギガバイトを実行できました。それはまだ多くのCPUを使用していなかったので、SQLを妨げているのは何ですか?
NETWORK_IO
は、300万件の「影響を受けた1行」メッセージが返送されている可能性があります。SET NOCOUNT ON
スクリプトに追加してみましたか?
EE_WaitStats*.xel
ため、古いカードは結果を汚染します。
SET NOCOUNT ON
もそれに追加します。