Home > C# > PostgreSQL > Npgsql > ドキュメント > 性能

性能 Npgsql

新規作成日 2019-03-03
最終更新日

性能

Npgsqlを使用して、PostgerSQLを使用する際の性能を向上させるための情報です。

Performance

準備済みのステートメント

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ソケットのディレクトリを指定するだけです。-このパラメータが、スラッシュで始まる場合、ファイルシステムのパスを意味すると解釈されます。

このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」