2017-06-23 6 views
2

現在、libpqを使用してPostgreSQL用のアダプタを実装していますが、PQsetSingleRowMode(https://www.postgresql.org/docs/9.6/static/libpq-single-row-mode.html)で設定された単列モードがパフォーマンス上の問題を抱えているのではないかと疑問に思っていましたか?PQsetSingleRowMode低性能

このモードでは、libpqはカーソルと明示的FETCHで実現できるものよりも、よりインテリジェントで効率的なバッファリングを使用するという印象を受けました。

ただし、単純なクエリ(「select mytable from id」、5000レコード)を10回実行しているとき。 (一度にすべて)

  • PQexecParams:78ミリ秒
  • PQsetSingleRowMode:3047ミリ秒(そのほとんどがで過ごした(クライアントとサーバーの両方側)のPostgreSQL 9.6.3で、私は以下の演奏パターンを観察していますPQgetResultの)
  • PQexecParams + 1 FETCH:3313ミリ秒(そのほとんどが10 FETCH +
  • PQexecParams)PQgetResultのに費やさ:219ミリ秒

そこで単一行モードが作成よりかろうじてより効率的であるように見えます交流ursorと行ごとに行をフェッチする...正しい動作ですか?または、単一行モードを制御する他のオプションがありますか?

(選択は単一行モードの間で実際にあるか、一度にいくつかのレコードをフェッチするので、私の使用状況の例では、一度にすべてを取得することは、いくつかのクエリのためのメモリ使用量の面で危険なことでしょう)

エクストラ質問:途中で一列モードを簡単にフェッチする方法はありますか? カーソル+これは簡単ですが、単一行モードのために、あなたのどちらかがすべての結果を取得したり、PQcancelを使用する必要が表示されますフェッチを使用して)

補遺: は、プロファイラで別の実行を持っていたが判明しましたPQgetResultはmallocを呼び出し、freeはボトルネックです(それぞれCPU時間の約60%と30%)。どちらの関数もMSVCR120 AFAICTから来ています(これはWin 10の下にあり、サーバーはlocalhostです)。私はlibpq.dllを "公式の" PostgreSQL zipから使用しています。面白いことに、ベンチマークの前に他のクエリを実行すると、「時には」問題が消えてしまうことがあります。 PQgetResultがmalloc/freeの弱点に当たっているようです。

答えて

1

これは驚くべきことです。

PQgetResultへの繰り返しのコールに一定のオーバーヘッドがあることは間違いありませんが、実際にはそれほど多くはありません。

localhostのデータベースで500万行を返すクエリでテストを実行しました.1回のローモードでは、CPUユーザーの2倍以上の時間が必要でした(合計実行時間はデータベースサーバーの処理時間が支配的でした)。

5000行3秒間、魚が鳴っているかもしれません。

実行可能ファイルをプロファイリングして、時間の所要時間を確認してください。

+0

プロファイラで別の実行があった場合、PQgetResultがmallocを呼び出し、freeがボトルネック(それぞれCPU時間の約60%と30%)であることがわかります。両方の関数はMSVCR120から来ていますローカルホスト)。私はlibpq.dllを "公式の" PostgreSQL zipから使用しています。面白いことに、ベンチマークの前に他のクエリを実行すると、問題が消えることがあります。PQgetResultがmalloc/freeの弱点に当たっているようです。 –

関連する問題