sql >> データベース >  >> RDS >> PostgreSQL

Postgresqlのjoin_collapse_limitとクエリプランニングの時間

    PostgreSQLの新しい9.4バージョン(この記事の執筆時点ではまだリリースされていません)は、EXPLAINに計画時間を追加します。 およびEXPLAIN ANALYZE 、およびそれらを使用できるようになります。

    古いバージョンの場合、想定は正しいです。計画時間を決定するためのより良い方法は、単純なEXPLAINを実行することです。 (ANALYZEはありません )そして、psqlでかかった時間をチェックします \timingを有効にすることでそれを行うことができます (私は通常、~/.psqlrcでそれを行います 。

    PostgreSQLハッカーチームはすでにそれをより大きな値に上げることについて話し合っています 。しかし、すべての場合に適しているとは保証できなかったようです。

    問題は、Nの最適な結合順序を見つける計画があることです。 テーブルはO(N!)を取ります (階乗)アプローチ。したがって、レイズの数値は非常に高く、次のクエリで簡単に確認できます。

    $ SELECT i, (i)! AS num_comparisons FROM generate_series(8, 20) i;
     i  |   num_comparisons   
    ----+---------------------
      8 |               40320
      9 |              362880
     10 |             3628800
     11 |            39916800
     12 |           479001600
     13 |          6227020800
     14 |         87178291200
     15 |       1307674368000
     16 |      20922789888000
     17 |     355687428096000
     18 |    6402373705728000
     19 |  121645100408832000
     20 | 2432902008176640000
    (13 rows)
    

    ご覧のとおり、デフォルトの8では最大で約40Kの比較を行い、提案した10では3Mになります。これは、最近のコンピューターではまだそれほど多くありませんが、次の値が大きくなりすぎて、増加するだけです。速すぎると、20は正気ではありません(21!は64ビット整数にも適合しません)。

    もちろん、16のような大きな値に設定できる場合もあります。これは、(理論的には)最大約20兆の比較を行うことができますが、それでも非常に優れた計画時間です。これは、PostgreSQLが計画中にいくつかのパスをカットし、必要がないためです。 常に すべての注文を確認しますが、常にそうであり、そのような高い値をデフォルトにすることを想定すると、私には良いアプローチのようには見えません。将来、すべての注文をチェックするという予期しないクエリが発生する可能性があります。その後、サーバーを停止させるクエリは1つだけになります。

    私の経験では、優れたサーバーへのインストールではデフォルト値として10を想定しており、そのうちのいくつかは12を使用しています。必要に応じて10に設定することをお勧めします。場合によっては、より高く設定してみてください(私は12)を超えることはなく、それがどのように動作するかを(綿密に)監視し続けます。




    1. ログテーブル用のMySQLストレージエンジン

    2. Oracle-過去1年間のデータを取得(動的)

    3. MySQL:別の列の値に基づく列の合計

    4. 主キーの更新と主キーの削除+挿入