2012,11,09, Friday
前回までで解説した、第xN分位数とジニ係数を求める関数を、実際に使ってみます。
まず、次のような1フィールド5レコードのテーブルを用意します。 psql=> select * from sampleTable;上記のテーブルを対象に、次のような SQL を実行します。 arraySorted() は、引数として与えられたデータを昇順に配列に格納してその配列を返す集約関数であり、percentile() は昇順ソート配列からN分位数を求める(通常)関数、同様に gini() は昇順ソート配列からジニ係数を求める(通常)関数です。 psql=> select上記のように、それぞれが正しく求められています。 さて、上記の SQL を書いていて、ふと気になったことがありました。 この SQL では SELECT リスト中で6つの arraySorted() が使われています。 それらに渡される引数は6回とも num であり、どの arraySorted() も同じ結果を返すことが自明です。 この場合、SQL に記述されたとおりに arraySorted() が6回(状態遷移関数レベルだと5行×6回=30回)コールされるのだとすると、極めて冗長で無駄な処理となります。 恐らく PostgreSQL はこのコールを1回で済ますように最適化してくれる、と希望的に観測しましたが、確信は持てない。 そこで、以下のような実験をしてみました。 まず、集約関数 arraySorted() を構成する状態遷移関数 insArraySorted() 中で、raise 文を使ってメッセージテキストを表示するようにします。 -- insArraySorted() : 新規エレメントを昇順ソート配列中の適正な位置に挿入するそして、arraySorted() を1回だけ使用する、下記のような SQL を実行します。 すると結果は、 psql=> select上記のとおり、状態遷移関数はテーブルの行数分(=5)呼び出されるので、5回のメッセージテキストが表示されます。 次に、先の SQL 文を実行します。 今度は arraySorted() が6回使われていますから、もし最適化が行われていなければ、5行×6回=30回のメッセージテキストが表示されることになります。 その結果は、 psql=> selectこのとおり、前の SQL と同じく、表示されるメッセージテキストは5回だけ。 実行結果は正しく表示されていますから、見事に最適化されていることが判りました。 めでたし、めでたし。 でも、これって常識? <この項、おしまい>
| http://blog.wakita.cc/index.php?e=89 |
| サーバ・Linux::PostgreSQL | 01:38 PM | comments (0) | trackback (0) | |
コメント
コメントする
|
この記事のトラックバックURL
http://blog.wakita.cc/tb.php/89
トラックバック
|