SQL BULK挿入/ BCPエクスポート後に使用済みメモリが解放されない


10

次のように非常に基本的なSQLテーブルを作成しました

CREATE TABLE [dbo].[TickData](
[Date] [varchar](12) NULL,
[Time] [varchar](12) NOT NULL,
[Symbol] [varchar](12) NOT NULL,
[Side] [varchar](2) NOT NULL,
[Depth] [varchar](2) NOT NULL,
[Quote] [varchar](12) NOT NULL,
[Size] [varchar](18) NOT NULL
    ) ON [PRIMARY]

次に、3ギガの一括挿入を実行しました

    BULK
    INSERT TickData
    FROM 
    'C:\SUMO.csv'
    GO

次に、SQLサーバーのRAM使用量はSkyrockingになり、最大30GoのRAMを消費しました。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

これは異常な動作であると考えるのが好きで、これを回避するためにそのアクションを実行できます。

編集:
OK、これはデフォルトの動作のようです。けっこうだ。
しかし、なぜ一括挿入が完了した後もメモリが解放されないのですか?

いくつかの特別な考慮事項:
SQLサーバーがOSから「伝えられた」ときにメモリを解放することに関するコメントのように、24コア32 Gb Xeonサーバーでの実地経験では、これが不正確であることが証明されています。抽出されたデータを処理する必要があるデータ処理アプリケーションの.Netインスタンスのプールがあり、残りのメモリを共有してジョブを実行しようとするため、窒息状態のままになっています。SQLServerがオンになったときよりも時間がかかります。オフにすると、すべてのアプリケーションでメモリを共有できます。SQL Serverエージェントを停止して、すべてがスムーズに進み、Articialltが原因でOutOfMemmroy Exceptionが発生してアプリがクラッシュしないようにする必要があります。人工的な残忍なメモリキャッピング/制限に関して、空きメモリが利用可能な場合、なぜそれを使わないのですか?理想的には、「ランダム」に強制的に制限されるだけでなく、利用可能なものに順応するように動的に設定されるのが理想的です。しかし、これは仕様によるものであるため、この最後の点でケースはクローズされました。


6
SQL Serverがメモリを解放する必要があるのはなぜですか?この操作を一度実行するためにメモリが必要な場合は、再度必要になります。SQL Serverがメモリを解放した場合、何に使用しますか?なぜメモリを解放する必要があるのですか?メモリを別の目的で使用すると、この一括挿入が再度実行されますが、どうなりますか?
アーロンバートランド

これを回避するために実行できる唯一のアクションは、最大メモリサイズを設定することです。メモリを「回復」するには、SQL Serverサービスを再起動します。明らかに、それによってメモリが解放され、サービスが再起動すると、通常どおりメモリが割り当てられます。
TMN 2012

最後の編集をクリーンアップしました。SQL Server(またはその他のDBエンジン)のコーディング方法のメリットや問題について議論/議論をしたい場合は、それを行うのにより良い場所を見つけてください。元の質問は、明らかに正しく十分に回答されています。このQが忍び寄ると、ロックされる可能性があります。
JNK、2012

質疑応答サイトではなく、答えを知り、方法論について話し合うことには何の問題もありません。チャットやフォーラムでこのディスカッションを間違いなく開催できますが、Stack Exchangeはもう少し構造化されており、ディスカッションの質問はすぐに終了します。
JNK、2012

3
また、非モデレーターとして、なぜサーバーでSQL以外のものを実行しているのでしょうか。ボックスはSQL Server専用に予約する必要があります。これはDBA 101のようなものです。エンジンは共有リソース環境用に設計されていません。
JNK

回答:


12

SQL Serverがバッファプールにできるだけ多くのメモリを割り当てるのは、通常の動作です。データベースは、大量のバッファで最適に機能します。動作を変更したい場合は、「最大サーバーメモリ」設定を設定できます。これに関するいくつかの良い背景資料はこちらです。


1
あなたの編集に関して、アーロンのコメントは良いものです。その理由は、データベースサーバーがメモリを解放する意味がほとんどないためです。SQL Serverは、メモリプレッシャーに対応し、必要に応じてメモリを解放しますが、実際には必要ありません。
Matt Whitfield、

@MikaJacobi申し訳ありませんが、2回目の編集は間違っています。開発者の考え方から私はあなたの見解を理解していますが、共存する一連のアプリケーションを構築することと、マシン上で実際にメモリを消費する唯一のサービスであるサーバーサービスを構築することには違いがあります。SQL Serverを「通常の」アプリケーションのように動作させたい場合は、最大メモリを設定して離れてください。あなたの質問はなぜそれがこのように機能するのかということでした、そしてそれは答えられました。あなたの質問が「まあ私はそれがそのように機能するのが好きではない」である場合-申し訳ありませんが、それはもう質問ではありません。
アーロンバートランド

けっこうだ。私の見解は、これをオンまたはオフにするオプションがあるべきだということであり、SQLサーバーがサーバー上の唯一のアプリケーションであるという仮定は本当に乱用です(大規模なネットワークを持つ大企業には当てはまるかもしれませんが、それだけではありません)可能であり、最も一般的な設定)
Mehdi LAMRANI

メモリを解放するためにSQL Serverが必要な理由がまだわかりません。他のアプリケーションがそれを必要とする場合、SQL Serverから取得し、SQL Serverが準拠します。これらの他のアプリケーションで必要になるまで、メモリを解放する目的は何ですか?
アーロンバートランド

1
@AaronBertrand Ok間違いかもしれませんが、私の最後の編集で述べたように、これは私が見たものではありません:他のアプリケーションがほとんど必要としないときにメモリが解放されず、メモリクラッシュの原因になりました(したがって、私の不満...)とにかく、みましょう主題を閉じます。それ以上議論する必要は実際にはないと思います。
Mehdi LAMRANI

7

OSでSQL Serverからメモリを取り戻す場合は、20 GBの大きなファイルをネットワーク経由でコピーします。SQL Serverは、OSが必要とするメモリを解放します。ただし、これが行われている間、さまざまなパフォーマンスカウンターを監視し、コピーの実行中または直後に再度実行すると、BULK INSERTのパフォーマンスがどのように変化するかを確認します。

これを手動で行う場合は、SQL Serverの最大サーバーメモリ設定に下限を設定し、サービスを再起動する必要があります。これで、SQL Serverは必要な場合でも28GBを使用しなくなります。しかし、これはSQL Serverを人為的に制限しているようです。

あなたが期待しているように見えるのは、時間の一部を空きメモリにできるより柔軟な動作です。何のために?これは、データベースファイルが再び大きくなるため他の目的に使用できないディスク領域を解放するためにデータベースファイルを圧縮するようなものですか?

おかしいですが、「SQL Serverが使えない理由」というGoogle検索を入力すると、最も一般的なオートコンプリートは「メモリの解放」です。



「あなたが期待しているように見えるのは、より柔軟な行動です。」丁度。SQLサーバーが利用可能なときにすべての利用可能なメモリを使用するようにしたいが、これらの重い瞬間が終わったら、「スリープ」状態に戻り、他のメモリを必要とするアプリケーションが快適に仕事を続けるようにします。この点に関する最新の最終編集)
Mehdi LAMRANI

私はこれを行う必要がある理由を説明する具体的なケースでは、あなたは質問の下部にあるJNKに私の最後のコメント@見てみることができます
メフディLAMRANI

4

残念ながらこれは仕様です。この投稿を参照してください。ただし、この投稿では、それを制御する方法についていくつかの説明を提供しています。

/server/251832/sql-server-bulk-insert-physical-memory-issue

メモリ割り当て編集

freed.NETアプリケーションと同じようにメモリを割り当てるため、メモリはアップしていません。メモリの割り当ては負荷が高いため、OSから要求されない限り、その割り当てが維持されます。しかし、恐れることはありません。OSがメモリを必要とする場合、.NETアプリケーションの場合と同じように、メモリを取得します。


@MikaJacobiもちろん、問題ありません。もう1つ注意すべき点として、SQL Serverもすべてのコアを引き継ぐので、使用できるコアの数を制限してください。SQL Serverが実際に実行されているオペレーティングシステムを実際に破壊するのを見たので、データセンターのSQL Serverをハードリブートする必要がありました。

知ってよかった。私は24コアを持っているので、これは今のところ大丈夫です。しかし、一括挿入が終了した後、なぜメモリが解放されないのですか?

一括挿入が完了している限り、OSがメモリを必要とする場合はメモリが割り当てられますが、.NETアプリケーションと同じようにメモリが割り当てられるため、必要な場合に他のユーザーがメモリを高速にアクセスできます。

私の手つかずの経験はこれと矛盾します(最後の編集を失います)
Mehdi LAMRANI
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.