本当の DBA の意見が必要です。Postgres 8.3 は、私の Macbook Pro でこのクエリを実行するのに 200 ミリ秒かかりますが、Java と Python は 20 ミリ秒 (350,000 行) 未満で同じ計算を実行します。
SELECT count(id), avg(a), avg(b), avg(c), avg(d) FROM tuples;
SQL データベースを使用する場合、これは正常な動作ですか?
スキーマ (テーブルには調査への回答が保持されます):
CREATE TABLE tuples (id integer primary key, a integer, b integer, c integer, d integer);
\copy tuples from '350,000 responses.csv' delimiter as ','
コンテキストのために Java と Python でいくつかのテストを作成しましたが、それらは SQL をクラッシュさせます (純粋な python を除く):
java 1.5 threads ~ 7 ms
java 1.5 ~ 10 ms
python 2.5 numpy ~ 18 ms
python 2.5 ~ 370 ms
sqlite3 でさえ、すべての列が文字列であると仮定しているにもかかわらず、Postgres と競合します (対照的に、Postgres で整数の代わりに数値列に切り替えるだけでも、10 倍の速度低下が発生します)。
成功せずに試したチューニングには次のものが含まれます(盲目的にいくつかのWebアドバイスに従います):
increased the shared memory available to Postgres to 256MB
increased the working memory to 2MB
disabled connection and statement logging
used a stored procedure via CREATE FUNCTION ... LANGUAGE SQL
私の質問は、ここでの私の経験は正常ですか?これは、SQL データベースを使用するときに期待できることですか? ACID にコストがかかることは理解できますが、これはちょっとおかしいと思います。リアルタイムのゲーム速度を求めているわけではありませんが、Java は 20 ミリ秒未満で数百万の double を処理できるため、少しうらやましく思います。
シンプルな OLAP を低価格で (お金とサーバーの複雑さの両方の点で) 実行するより良い方法はありますか? 私は Mondrian と Pig + Hadoop を調べましたが、さらに別のサーバー アプリケーションを維持することにそれほど興奮しておらず、それらが役立つかどうかもわかりません。
いわば、Python コードと Java コードは社内ですべての作業を行っています。それぞれ 350,000 個のランダムな値を持つ 4 つの配列を生成し、平均を取ります。タイミングには世代を含めず、平均化ステップのみを含めます。Java スレッドのタイミングは 4 つのスレッド (配列あたり平均 1 つ) を使用し、やり過ぎですが、間違いなく最速です。
sqlite3 のタイミングは Python プログラムによって駆動され、ディスクから実行されます (:memory: ではありません)。
Postgres が舞台裏でさらに多くのことを行っていることは認識していますが、これは読み取り専用データであるため、その作業のほとんどは私にとって重要ではありません。
Postgres クエリは、その後の実行でタイミングを変更しません。
Python テストを再実行して、ディスクからスプールすることを含めました。タイミングは大幅に遅くなり、4 秒近くになります。しかし、Python のファイル処理コードはほとんど C で書かれていると思います (csv lib ではないかもしれませんが)。これは、Postgres がディスクからストリーミングしていないことを示しています (または、あなたが正しいので、お辞儀をする必要があります)。誰がストレージ層を書く前に!)