性能
Npgsqlを使用して、PostgerSQLを使用する際の性能を向上させるための情報です。
準備済みのステートメント
Prepared Statements
最も重要な(そして、簡単な)方法の1つ、あなたのアプリケーションの性能を改善することは、あなたのコマンドを準備することです。ADO.NETに対して、直接、コーディングしていなくても、(例えば、DapperやO/RMを使用して)、Npgsqlは、準備済みステートメントに関連するパフォーマンスの向上の恩恵を受けることができる、自動の準備機能を持っています。詳細については、このブログの記事やドキュメントを参照してください。
バッチ処理/パイプライン化
Batching/Pipelining
あなたが、コマンドを実行するとき、Npgsqlは、データベースへの往復を実行します。あなたが、複数のコマンドを実行した(言い換えると、3行を挿入する、あるいは、複数の選択を実行する)場合、あなたは、複数の往復を実行しています。;次のコマンドが、実行を開始する前に、それぞれコマンドは、完了する必要があります。あなたのネットワークの待ち時間に応じて、これは、あなたのアプリケーションの性能をかなり低下させる可能性があります。
あなたは、1つのコマンドで、複数のSQL命令を1回の往復で実行するバッチ処理することができます。:
using (var cmd = new NpgsqlCommand("SELECT ...; SELECT ..."))
using (var reader = cmd.ExecuteReader())
{
while (reader.Read()) {
// Read first resultset
// 最初の結果セットを読み込む
}
reader.NextResult();
while (reader.Read()) {
// Read second resultset
// 2つ目の結果セットを読み込む
}
}
パフォーマンス・カウンタ
Performance Counters
Npgsql 3.2には、接続と接続プールに、表示属性を提供する、パフォーマンス・カウンタのためのサポートが含まれています。-これは、あなたのアプリケーションが、接続リークなどがあるかどうか、リアルタイムでしていることを理解するのことを助けます。Npgsqlカウンタのサポートは、SqlClientのような、他のADO.NETプロバイダと非常によく似ています。最初に、そのページを読むことをお勧めします。
あなたのWindowsのシステム上で、パフォーマンス・カウンタを使用することは、まず、それらを設定します。これを実行するには、あなたは、githubのリリース・ページで入手できるpgsqlのMSIをインストールする必要があります。GACのインストールが必要ではない(あるいは、推奨される)ことに、注意して下さい。一旦、カウンターがインストールされると、Windowsパフォーマンス・モニタを起動し、「PostgreSQL用.NETデータプロバイダ(Npgsql)」カテゴリを探します。
加えて、あなたは、接続文字列に、Use Perf Counters = trueを渡す必要があります。一旦、あなたが、この追加で、Npgsqlアプリケーションを起動すると、あなたは、Performance Monitorで、実時間のデータを見始める必要があります。
パフォーマンス・カウンタは、現在、.NET Frameworkを搭載したWindowsでのみ利用可能です。(.NET Coreには、まだパフォーマンス・カウンタが含まれていません)。
TransactionScopeへの参加を無効にする
Disable enlisting to TransactionScope
既定では、Npgsqlは、アンビエント・トランザクションに参加します。これは、ransactionScope内で接続が開かれたときに発生します。そして、トランザクションを処理するための強力なプログラミング・モデルを提供できます。しかしながら、これには、あなたが考えるより多くの時間がかかる操作の(プールされた)接続が開くたびに、アンビエント・トランザクションが、進行中かどうかを確認することが含まれます。接続の存続期間が非常に短く、オープン/クローズが非常に頻繁に発生するシナリオでは、このチェックを削除することでメリットが得られます。-接続文字列に、Enlist = falseを含めるだけです。あなたが、NpgsqlConnection.Enlist()を呼び出して、手動で参加させることができることに注意してください。
プールされた接続のリセット
Pooled Connection Reset
プールされた接続が、閉じているとき、Npgsqlは、次回の使用時に、その状態がリセットされるように手配します。これにより、物理的接続のある使用サイクルから、別の使用サイクルへの状態の漏洩を防ぐことができます。例えば、あなたは、特定のPostgreSQLパラメータ(statement_timeoutなど)を変更することができます。そして、接続が閉じられても、この変更が持続するのは望ましくありません。
閉じるときに、準備済みのステートメントがある場合、接続のリセットは、PostgreSQLのDISCARD ALLコマンドを介して、あるいは、(それらのステートメントを閉じないようにするため)ドキュメントに記述されている同等のステートメントの組合せによって、行われます。接続を閉じるとき、これらのステートメントは、実際には、送信されないことに注意してください。-それらは、Npgsqlの内部の書込バッファに記述されます。そして、接続が再開された後、最初のユーザー・ステートメントで送信されます。これは、高くつくデータベース往復を防ぎます。
あなたが、本当に、PostgreSQLから、性能の最後の小片を搾り取ることを望む場合、あなたは、あなたの接続文字列で、No Reset On Closeを指定することによって、無効にするかもしれません。-これは、接続が、とても短命なシナリオで、そして、特に準備済みステートメントが、使用されている場合、性能をわずかに改善します。
大きな値を読み込む
Reading Large Values
PostgreSQLから、結果を読み込むとき、Npgsqlは、最初に、ネットワークから、内部の読み込みバッファに未処理バイナリデータを読み込みます。そして、その次に、あなたが、NpgsqlDataReader.GetString()のような、メソッドを呼び出すときにそのデータを解析します。これにより、効率的なネットワークの読み取りが可能になりますが、この既定で8Kのバッファのサイズについて考える価値があります。通常の使い方では、Npgsqlは、それぞれの行をバッファに読み込もうとします。;その行全体が、8Kに収まる場合、あなたは、最適なパフォーマンスが得られます。しかしながら、行が、8Kより大きい場合、Npgsqlは、接続が、閉じられるか、プールに返されるまで、使用される、"oversize buffer"を確保します。あなたが、気をつけない場合、これは、あなたのアプリケーションを遅くする、かなりのメモリの混乱を生み出すことがあります。これを避けるために、あなたが、16kの行を読むことを知っている場合、あなたは、あなたの接続文字列に、Read Buffer Size = 18000を指定できます。(プロトコルのオーバーヘッドには、ある程度の余裕を見てください)、これにより、読み取りバッファが、確実に再利用され、余分な割り当てが発生しなくなります。
もう1つの選択肢は、CommandBehavior.SequentialAccessをpgsqlCommand.ExecuteReader()に渡すことです。シーケンシャル・モードは、Npgsqlが、行全体をバッファに読み込まなくなることを示していますが、必要に応じて、空のとき、より多くのデータのみを読み込むバッファを満たします。行の合計サイズに関係なく、同じ8Kの読み取りバッファが使用されます。そして、Npgsqlが、内容の世話を行う場合があります。シーケンシャル・モードでは、しかしながら、あなたは、行のフィールドを指定した順序で読む必要があります。;あなたは、2つ目のフィールドを読むことができません。そして、その次に、1つ目のフィールドに戻ります。そして、実行しようとすると、例外が発生します。同様に、あなたは、二回、同じフィールドを読むことができません。-一旦、あなたが、フィールドを読み込むと、利用され続けます。
CommandBehavior.SequentialAccessの詳細については、このページを参照してください。あなたが、この機能を使うことにした場合、それが、多くの場合、使用されないため、バグが含まれているかもしれないことを認識してください。
あなたは、Socket Receive Buffer Size接続文字列パラメータを設定することによって、ソケットの受信バッファサイズを制御することもできます。(Npgsqlの内部バッファと混同しないでください)
大きな値を書き込む
Writing Large Values
書込みは、やや似ています。-Npgsqlは、内部に、書き込みバッファを持っています。(これも、既定で、8K)。クエリのSQLとパラメータをPostgreSQLに書き込むとき、Npgsqlは、常に、"順番に"書き込まれます。つまり、8Kバッファをいっぱいにして、いっぱいになったらフラッシュします。あなたは、バッファの寸法を制御するWrite Buffer Sizeを使用することができます。
Socket Receive Buffer Size接続文字列パラメータを設定することによって、あなたは、ソケットの受信バッファサイズを制御することもできます。(Npgsqlの内部バッファと混同しないでください)
パラメータ値を書くときにボクシングを避ける
Avoiding boxing when writing parameter values
この項目を参照してください。
Unixドメイン・ソケット
Unix Domain Socket
あなたが、LinuxやMacOSを使っている、そして、同じマシンで、PostgreSQLサーバーに接続している場合、通常のTCP / IPソケットではなく、Unixドメイン・ソケットを介して接続することで、パフォーマンスを少し向上させることができます。これを実行するには、Host接続文字列パラメータに、PostgreSQLソケットのディレクトリを指定するだけです。-このパラメータが、スラッシュで始まる場合、ファイルシステムのパスを意味すると解釈されます。