Exadata Hybrid Columnar Compression に関する検証 その4
<Exadata Hybrid Columnar Compression に関する検証 その4>
ペンネーム: ベロ
前回より引き続き、Hybrid Columnar Conpressionの検証を実施していきます。
前回、Columnarたる所以をダンプから発見することは出来ませんでした。
CU(Compression Unit)と呼ばれる圧縮単位はOracle Block単位ではなく、複数
のOracle Blockをまたがった単位であることは分かりました。
しかしながら、CUの中身がどのような構造になっているのか、検証することが
できません。あまり、ここにこだわっていても埒があかないので、物的証拠を
探すよりも状況証拠を集める方針に切り替えることにします。
1. カラム単位で圧縮することで、パフォーマンス(Query)がどう変わるのか?
カラム単位で圧縮と言うと、カラム単位で別領域(別Block)にデータを格納
して、Queryアクセスもカラム単位でアクセスするのではないか?
そうすると、SELECT句の書き方で、パフォーマンスが大きく異なるのでは?
と想像できます。
以下、全カラムを選択 vs. 単一カラムを選択で、パフォーマンスがどう
変化するのか検証してみます。
ここで、有意な変化があるのなら、CUの中の”カラム単位”のブロックへの
アクセスをしているのではないかと推察できます。
全カラムを選択)
SELECT * FROM ARCHIVE_HIGH_COMPRESS_TABLE;
単一カラムを選択)
SELECT CUST_EMAIL FROM ARCHIVE_HIGH_COMPRESS_TABLE;
先ず経過時間から
全カラムを選択)
経過: 00:08:01.96
単一カラムを選択)
経過: 00:03:56.84
なるほど、経過時間は、全カラム選択時と比較して、約半分に減少しました。
ということは、CUの内部ではカラム単位でデータアクセスしていると言える。
いやいや、それだけでは何とも言えません。
経過時間と共に統計情報を見てみます。
全カラムを選択)
統計 ---------------------------------------------------------- 0 recursive calls 0 db block gets 1211607 consistent gets ^^^^^^^ ^^^^^^^^^^^^^^^ 204487 physical reads ^^^^^^ ^^^^^^^^^^^^^^ 0 redo size 961889541 bytes sent via SQL*Net to client ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 13011128 bytes received via SQL*Net from client 1182794 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 17741894 rows processed
単一カラムを選択)
統計 ---------------------------------------------------------- 1 recursive calls 0 db block gets 1199592 consistent gets ^^^^^^^ ^^^^^^^^^^^^^^^ 342135 physical reads ^^^^^^ ^^^^^^^^^^^^^^ 0 redo size 480834823 bytes sent via SQL*Net to client ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 13011128 bytes received via SQL*Net from client 1182794 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 17741894 rows processed
統計情報をみると、全カラム選択時も単一カラム選択時もconsistent gets
およびphysical readsに大きな変化は見られません。
唯一、bytes sent via SQL*Net toclientが、約半分になっています。
これは、経過時間が半分になったことと相関してます。
つまり、Columnarと言えども、内部的にカラム単位でアクセスするような動作
ではないのではないと思われます。それは、低レベルのブロックアクセスがカ
ラム単位の有無で変化がないことから想像できます。
では、なぜ、経過時間が約半分に減少したのでしょうか?
それは、上記で触れたbytes sent via SQL*Net to clientに関係します。
クライアントに返したデータ量が半分になったのです。それは、圧縮してある
データの展開量が半分になったと推定できます。
要は、Hybrid Columnar Compressionでは、データをクライアントに返す直前
に必要なデータの展開を行っているということです。
圧縮データの展開処理は、データをクライアントに返す直前に行う。となると
WHERE句の処理はどうなるのか?と疑問が湧いてきます。
2. WHERE句の有無でパフォーマンス(Query)に変化があるのか?
WHERE句の有無で、パフォーマンスが大きく異なる場合、データの展開処理の
場所と頻度が異なる可能性が高い。
以下、WHERE句の無いSQLと有るSQLでパフォーマンスを計測してみます。
WHERE句無し)
SELECT CUST_EMAIL FROM ARCHIVE_HIGH_COMPRESS_TABLE;
WHERE句有り)
SELECT CUST_EMAIL FROM ARCHIVE_HIGH_COMPRESS_TABLE WHERE CUST_EMAIL like '%@%';
以下、経過時間と統計情報です。
WHERE句無し)
経過: 00:03:56.84 統計 ---------------------------------------------------------- 1 recursive calls 0 db block gets 1199592 consistent gets 342135 physical reads 0 redo size 480834823 bytes sent via SQL*Net to client 13011128 bytes received via SQL*Net from client 1182794 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 17741894 rows processed
WHERE句有り)
経過: 00:03:58.86 統計 ---------------------------------------------------------- 1 recursive calls 0 db block gets 1199592 consistent gets 342135 physical reads 0 redo size 480834823 bytes sent via SQL*Net to client 13011128 bytes received via SQL*Net from client 1182794 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 17741894 rows processed
WHERE句の有無でパフォーマンスに有意な差は見られません。つまり、WHERE句
の処理は、通常(非圧縮データ)のように、データブロックを検索して結果を
得るのではなく、どこか別のメタデータ(一種のインデックス)を使用して
いるのではないかと推察されます。
このメタデータを経由して、実データへアクセスすることで展開処理がなく
ても(オーバーヘッドを最小化して)検索が実行できるものと思われます。
ではでは、メタデータにはどんなものがあるのでしょうか?
これは、現在のところ想像の域を出ませんが、きっと、圧縮前のデータと
それを使用しているROW、(もしくはカラム)へのポインタ情報ではないか?
ではでは、実データにアクセスしない(と思われる)方法、つまりメタデータ
のみアクセス出来そうなものは何か?
きっとCOUNT(*)系のアクセスだと、メタデータ+そのポインタのみのアクセス
で完了して、実データへはアクセスしなくて良い可能性が高い。
3. メタデータにはどんなデータを管理しているのか?
また、メタデータだけのアクセスが可能なのか?
以下のSQLを実行してみます。
SELECT COUNT(*) FROM ARCHIVE_HIGH_COMPRESS_TABLE;
メタデータが先程、筆者が想像したような構造になっている場合、実データ
へのアクセスは行わず、メタデータから必要なポインタ計算のみ実行すること
でアクセスは相当高速化されるはずです。
経過: 00:00:00.95 統計 ---------------------------------------------------------- 0 recursive calls 0 db block gets 15927 consistent gets ^^^^^ ^^^^^^^^^^^^^^^ 15898 physical reads ^^^^^ ^^^^^^^^^^^^^^ 0 redo size 448 bytes sent via SQL*Net to client 416 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
思った通りです。先程のCOUNT(*)でないSQLの場合、consistent gets +
physical reads で1416094となっていましたが、今回のCOUNT(*)では31825
と大幅に減少しています。また、経過時間も1秒未満となっています。
つまり、メタデータの大きさはこの31825 block(未満)程度の大きさでは
ないかと大まかに推測できます。
ちなみに、COUNT(*)ではなく、カラム名を入れてCOUNTを取得すると以下
のようになりました。
SELECT COUNT(CUST_EMAIL) FROM ARCHIVE_HIGH_COMPRESS_TABLE; 経過: 00:00:09.37 統計 ---------------------------------------------------------- 1 recursive calls 0 db block gets 16842 consistent gets ^^^^^ ^^^^^^^^^^^^^^^ 17738 physical reads ^^^^^ ^^^^^^^^^^^^^^ 0 redo size 457 bytes sent via SQL*Net to client 416 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
COUNT(*)と比較すると、consistent gets や physical readsに大きな変化は
ありませんが、経過時間が大きく異なります。
これは、メタデータから、COUNT(*)のようなカラム情報がないものを検索する
より、カラム情報を特定するオーバーヘッドがかなり高いと想像できます。
ということで、今回の検証はこの辺にしておきます。今回の検証は想像を含め
た状況証拠を見てみることに集中しました。その中で、以下のようなことが言
えると思われます。
1. Hybrid Columnar Compressionの最小アクセス単位はCUであり、Columnarと
言っても、Column単位でのアクセスではないと思われる
2. 圧縮データの展開はクライアントのデータを返す直前であり、圧縮データ
の検索はメタデータを使用しているに違いない
3. そのメタデータからカラムデータを特定するオーバーヘッドは、結構高い
と思われる
ちょっと春の兆しが感じられる 恵比寿より