2

約 300,000++ 行を含む CSV ファイルから読み取る VB Web アプリケーションがあります。アプリケーションは行ごとに読み取り、行ごとに、約 100,000++ レコードを含む SQL Server データベース内のテーブルをクエリし、クエリの結果に基づいて、アプリケーションは別のことを行います。sqlservr.exe は、4 GB の開発マシンでメモリ消費量を最大にします。

そこで、ループ クエリの観点から SQL Server のパフォーマンスをテストするための簡単なアプリケーションを作成しました。

Dim Connection As New SqlConnection(ConfigurationManager.ConnectionStrings("SiteSqlServer").ConnectionString)
Dim Command As New SqlCommand("", Connection)
Connection.Open()
For i As Integer = 0 To 20000
    Command.CommandText = "SELECT CustomerID FROM Customer WHERE CustomerID = " & i
    Command.ExecuteScalar()
Next
Connection.Close()

このコードが実行されるたびに、sqlservr.exe はさらに 100MB++ のメモリを占有し、コードの実行が終了した後でもメモリを解放しません。

これは正常ですか?この影響を軽減する方法はありますか?

4

3 に答える 3

2

これを試して:

For i As Integer = 0 To 20000
    Command.CommandText = "SELECT CustomerID FROM Customer WHERE CustomerID = " & i
    Command.ExecuteScalar()
    Command.Dispose()
Next

Dispose()呼び出しはあなたの後ろでクリーンアップする必要があり、影響を軽減する可能性があります。

于 2011-06-13T13:54:29.360 に答える
2

いくつかの理由により、SQL Serverはメモリをすぐにシステムに解放しません(http://sqlnerd.blogspot.com/2006/07/memory-use-in-sql-server.htmlを参照)。

とにかく、動的SQLクエリの代わりにストアドプロシージャを使用する必要があります。SQL文字列を毎回解析する必要がないため、SQLServerはより効率的に機能します。

確かにそうですが、再確認してください。クエリしているテーブルが適切にインデックス付けされていることを確認してください。

可能であれば、事前に.csvファイルをSQLサーバーにロードすることも検討してください。.csvデータをSQLServerのインデックス付きテーブルに含めると、すべてが簡単になります。それらをどれだけ最適化しても、SQL Serverへの100kラウンドトリップは、結合とサーバーを活用することで簡単に節約できる可能性のあるリソースを消費します。サイドオペレーション。

于 2011-06-13T13:59:04.757 に答える
0

はい、正常です。一般に、SQL Serverは、メモリを取得するとメモリを解放しません。結果をできるだけ早く提供することが目的であり、RAMにキャッシュされているデータがある場合は、より迅速にクエリを実行できます。SQL Serverは、内部で取得したメモリブロックを再利用する場合がありますが、実行中はそれらを解放しません。これは仕様によるものです。これを読んでみてください

これは、一般に、SQL Serverを本番環境の別のボックスで実行して、他のメモリアプリケーション(IISなど)と競合しないようにする必要がある理由でもあります。

于 2011-06-13T13:59:37.720 に答える