都内で働くSEの技術的なひとりごと / Technical soliloquy of System Engineer working in Tokyo

都内でサラリーマンやってます。SQL Server を中心とした (2023年からは Azure も。) マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。英語の勉強のため、英語の

発表されたときはすごいなーと思いながらも、多分業務で使うことはしばらくないだろうなーと思っていたら、いきなり使うことになりそうなので急遽列ストアインデックスについてお勉強を始めてみる

 早速お勉強。まず、基本概念から。
列ストア インデックスの説明

SQL Server のインメモリ列ストア インデックスは、列ベースのデータ ストレージと列ベースのクエリ処理を使用して、データを格納および管理します。 列ストア インデックスは、主に一括読み込みと読み取り専用のクエリを実行するデータ ウェアハウスのワークロードで適切に動作します。 従来の行指向ストレージの最大 10 倍のクエリ パフォーマンスと、非圧縮データ サイズの最大 7 倍のデータ圧縮を達成するために列ストア インデックスを使用します。

 一括更新向きなんですね。OLTP 系には不向きなのかな?なんか日本語がわかりづらい。

列セグメントの断片化を低減し、パフォーマンスを高めるために、列ストア インデックスでは、一部のデータおよび削除された行に対応する ID の B-Tree を一時的に行ストア テーブルに格納することがあります。 デルタストア操作は内部で処理されます。 列ストア インデックスは、正しいクエリ結果を返すために、列ストアとデルタストアの両方からのクエリ結果を結合します。
デルタストア
クラスター化列ストア インデックスでのみ使用されるデルタストアは、行数が列ストアに移動できる規模になるまで行を格納する行ストア テーブルです。 デルタストアは、読み込みやその他の DML 操作のパフォーマンスを高めるために、クラスター化列ストア インデックスで使用されます。
大規模な一括読み込みでは、行のほとんどがデルタストアを通らずに列ストアに直接移動します。 一括読み込みの最後に位置する行の数は、行グループの最小サイズである 102,400 行を満たすには足りないことがあります。 この場合、それらの行は列ストアではなくデルタストアに移動します。 102,400 行未満の小規模な一括読み込みでは、すべての行がデルタストアに直接移動します。
デルタストアは、最大行数に達すると閉じられます。 閉じている行グループは、組ムーバー プロセスによって確認されます。 閉じている行グループが見つかると、その行グループが圧縮され、列ストアに格納されます。

 tuple-move というプロセスによって、102,400 以上になったらデルタストアから列ストアに移動するのか。

deltastore
Used with clustered columnstore indexes only, a deltastore is a rowstore table that stores rows until the number of rows is large enough to be moved into the columnstore. A deltastore is used with clustered columnstore indexes to improve performance for loading and other DML operations.
During a large bulk load, most of the rows go directly to the columnstore without passing through the deltastore. Some rows at the end of the bulk load might be too few in number to meet the minimum size of a rowgroup which is 102,400 rows. When this happens, the final rows go to the deltastore instead of the columnstore. For small bulk loads with less than 102,400 rows, all of the rows go directly to the deltastore.
When the deltastore reaches the maximum number of rows, it becomes closed. A tuple-move process checks for closed row groups. When it finds the closed rowgroup, it compresses it and stores it into the columnstore.

 この図がわかりやすいですね。
f:id:koogucc11:20160629023502p:plain

図が示すように、クラスター化列ストア インデックスにデータを読み込むには、SQL Server は次のように動作します。
最大サイズの行グループを列ストアに直接挿入します。 データが読み込まれると、SQL Server は開いている行グループに先着順でデータ行を割り当てます。
それぞれの行グループが最大サイズに到達すると、SQL Server は次の処理を行います。
行グループを CLOSED としてマークします。
デルタストアをバイパスします。
列ストア圧縮を使用する行グループで、それぞれの列セグメントを圧縮します。
圧縮された列セグメントを列ストアに物理的に格納します。
次のように、列ストアまたはデルタストアに残りの行を挿入します。
行数が行グループの最小限の行数の要件を満たしている場合は、行が列ストアに追加されます。
行数が行グループの最小限の行数の要件を満たしていない場合は、行がデルタストアに追加されます。

 非クラスター化列ストア インデックスの場合
f:id:koogucc11:20160629023609p:plain

 ふむ、結構辛そうね。

パフォーマンスに関するヒント
列ストア インデックスを並列で作成するための十分なメモリの計画
列ストア インデックスの作成は、メモリに制限がない限り既定で並列操作になります。 インデックスを並列で作成するには、インデックスを順次作成する場合よりも多くのメモリが必要です。 十分なメモリがある場合、列ストア インデックスの作成には、同じ列で B-Tree を構築する場合の約 1.5 倍の時間がかかります。
列ストア インデックスを作成するために必要なメモリは、列数、文字列型の列数、並列処理の最大限度 (DOP)、およびデータの特性によって異なります。 たとえば、テーブル内の行数が 100 万未満の場合、SQL Server はスレッドを 1 つだけ使用して列ストア インデックスを作成します。
テーブルに 100 万を超える行があり、SQL Server で MAXDOP を使用してインデックスを作成するための十分なメモリ許可を取得できない場合、SQL Server は必要に応じて自動的に MAXDOP を減らし、使用できるメモリ許可に合うように調整します。 場合によっては、メモリが制限された状況でインデックスを構築できるように、DOP を 1 まで小さくする必要があります。

 眠い。今日のカラムストアインデックスのお勉強は以上です。

Type-C 用にケーブル買ってみよう、と思ったけど使い道あるのか?

f:id:koogucc11:20160625190318j:plain

 VGA アダプタも必要です。
http://shopap.lenovo.com/SEUILibrary/controller/e/jpweb/LenovoPortal/ja_JP/catalog.workflow:item.detail?hide_menu_area=true&GroupID=460&Code=4X90K86568shopap.lenovo.com

 yoga mouse ほしいなぁ。日本国内では売ってないんだよな。
www.gizmag.com