テーブル作成
どうもこんにちは。ilovegpdbです。
前回が力みすぎたので今日は気軽に行きます。
テーブルをつくって遊ぶ
インストールしたはいいけどテーブルがないと何もできないですね。
SQLはだいたいPostgreSQLと同じなのでPostgreSQL使ったことがあると何かと便利ですよ。
-- テーブルを作る CREATE TABLE sales( order_no bigint, product_code char(8), sales_time timestamp ) DISTRIBUTED BY (order_no);
みたいな感じにしてみました。あくまで例です。
CREATE TABLEと列定義は標準SQLとほぼ互換なので問題ないですね。後ろにDISTRIBUTED BY句がついています。Greenplumはシェアードナッシングのデータベースなので、セグメントサーバが一つのテーブルを水平分割して持ちます。このときの分散ポリシーをテーブル毎に決定できるわけです。キーはハッシュ関数にかけられてその結果で保存ノードが決まります。ハッシュテーブルのバケットがノードになった感じですね。ちなみにDISTRIBUTED RANDOMLYを指定すると完全にランダムに(ラウンドロビンで)分散されます。一見素敵な分散ポリシーに見えますが、分散キーはクエリの性能を左右するので決めておくことが重要です。そのうちわかります。
SELECT
db1=# INSERT INTO sales SELECT order_no, lpad((order_no / 2)::text || (order_no % 10), 8, '0'), '2010-01-01 00:00:00'::timestamp + ('' || order_no || 'min')::interval FROM generate_series(1, 1000000)order_no; INSERT 0 1000000 Time: 7583.776 ms
generate_series()もPostgreSQLと同様に使えるので便利ですね。
db1=# SELECT * FROM sales LIMIT 10; order_no | product_code | sales_time ----------+--------------+--------------------- 1 | 00000001 | 2010-01-01 00:01:00 3 | 00000013 | 2010-01-01 00:03:00 5 | 00000025 | 2010-01-01 00:05:00 7 | 00000037 | 2010-01-01 00:07:00 9 | 00000049 | 2010-01-01 00:09:00 11 | 00000051 | 2010-01-01 00:11:00 13 | 00000063 | 2010-01-01 00:13:00 15 | 00000075 | 2010-01-01 00:15:00 17 | 00000087 | 2010-01-01 00:17:00 19 | 00000099 | 2010-01-01 00:19:00 (10 rows) Time: 10.978 ms db1=# SELECT count(*), avg(substr(product_code, 4, 4)::int) FROM sales; count | avg ---------+-------- 1000000 | 4999.5 (1 row) Time: 399.057 ms
集計機能も問題なし。EXPLAINしてみます。
db1=# EXPLAIN ANALYZE SELECT count(*), avg(substr(product_code, 4, 4)::int) FROM sales; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------ Aggregate (cost=16845.37..16845.38 rows=1 width=9) Rows out: 1 rows with 1694 ms to end, start offset by 0.372 ms. Executor memory: 8K bytes. -> Gather Motion 2:1 (slice1; segments: 2) (cost=16845.31..16845.35 rows=1 width=9) Rows out: 2 rows at destination with 1677 ms to first row, 1694 ms to end, start offset by 0.375 ms. -> Aggregate (cost=16845.31..16845.32 rows=1 width=9) Rows out: Avg 1.0 rows x 2 workers. Max 1 rows (seg0) with 1693 ms to end, start offset by 0.716 ms. Executor memory: 8K bytes avg, 8K bytes max (seg0). -> Seq Scan on sales (cost=0.00..11842.20 rows=500310 width=9) Rows out: Avg 500000.0 rows x 2 workers. Max 500001 rows (seg0) with 0.036 ms to first row, 674 ms to end, start offset by 0.717 ms. Slice statistics: (slice0) Executor memory: 221K bytes. (slice1) Executor memory: 240K bytes avg x 2 workers, 240K bytes max (seg0). Total runtime: 1694.183 ms (14 rows) Time: 1695.052 ms
二段で集計している様子が伺えますね。Greenplumはセグメントサーバを並列処理させることでクエリの高速化を図ります。分散集計はまさにこの典型で、いったんセグメント内で集計してからマスタサーバにかき集めて再集計しているようです。
まとめ
とりあえずSQLを実行しました。簡単なSQLの実行を確認できました。
ちなみに今回からxlargeインスタンスを使うことにしましたので、もう少し1ノードでセグメント数を増やしてみたいと思います。また、PostgreSQL単体の処理と比較してどのぐらい違うか比べてみたいです。