(概要)
これから説明する内容のロードマップとして、最初に、さまざまな実施形態の概要を説明し、次いで、補足的コンテキスト(supplemental context)および理解のために、例示的で非限定的な任意選択の実施態様についてより詳細に論じる。次いで、ランレングスエンコード(run length encoding)とビットパッキングの性能上の利益を、ハイブリッド圧縮技法によって適応的にトレードオフする実施形態を含む、大量のデータをパックする列ベースエンコード技法に関するある補足的コンテキストを説明する。最後に、さまざまな実施形態を実現し、または展開することができるある代表的なコンピューティング環境および装置を記載する。
背景の項で論じたとおり、とりわけ、従来のシステムは、現在の圧縮技法の限界、ネットワークを横切る伝送帯域幅の限界およびローカルキャッシュメモリの限界のため、サーバまたは「クラウド(cloud)」内のデータストアからの莫大な量のデータを、非常に高速にメモリに読み込む問題を適切に処理しない。リアルタイム要件を有するさまざまな異なるデータ集約的なアプリケーションによって多数のクエリが実行されると、この問題は複合化し、大量のデータに関するフィルタリングおよび/または並べ替えを巻き込むクエリは、このような演算のコストのため、固有の難問を提示する。
この点に関して言えば、本明細書のさまざまな実施形態に関連して説明したとおり、行を全く並べ替えないことによって、あるいはデータウィンドウのサイズに関連した行数に一致するか、またはそれよりも少ない非常に小数の行だけを並べ替えることによって、高い割合の行または全ての行のコストのかかる並べ替えを含むシナリオが回避される。外部クエリ要求を、2つの異なる内部副要求、すなわち指定されたWHERE節およびORDER BY列に対する行の分布についての統計量を計算する第1の内部副要求と、この統計量に基づいて、ウィンドウにマッチする行だけを選択する第2の内部副要求とに分割することができる。
この点に関しては、後にデータをウィンドウイング(windowing)するため、WHEREおよびORDER BYに依存する動的に得られた統計量をレバレッジ(leverage)する。ある実施形態では、統計量の構築時間を最小化するため、実データ値、またはヒストグラム構築を容易にするために離散化した(discretized)後の合成データ値に対して統計量を構築する。この点に関して言えば、合成(「離散化された」)データは、結合された列の形態として処理されて、ORDER BY演算に加わる。
さらに、後により詳細に説明する実施形態と一致して、ORDER BY演算によって巻き込まれる列の内容が分析された後のO(n)内の2次スキャンまで、最終ウィンドウが生成されない。さらに、あるケースでは、この方法が、予め計算された階層データを使用して、あるタイプの合成(「離散化された」)列をシミュレートする。一実施形態では、あるアルゴリズムが、所与のデータに対する適当な離散化方法、ならびにクエリ定義、統計量から決定される最終ウィンドウの内容および並列化(parallelization)の程度に基づくバッファリング戦略を選択する。
さらに、本明細書では、WHEREバケット(bucket)およびORDER BYバケットの内容ならびに統計量から決定される最終ウィンドウの内容に基づいて射影(projection)法を選択するあるアルゴリズムを提示する。さらに、ある方法は、最大N個、例えば3つの予め構成されたバッファのうちの1つのバッファへの挿入だけを使用して最終ウィンドウを並列に構築することを備える。他の実施形態では、クエリ仕様(query specification)、選択された離散化法、ヒストグラムによって決定される最終ウィンドウ内のデータの分布、およびデータ処理に適用される並列化の程度に従って、射影中に使用する内部バッファ、例えばバッファサイズおよびそれらのポリシーを構成するプロセスを説明する。
並列処理に関して、セグメント離散化は、ORDER BYのない(WHEREフィルタだけを有する)クエリに対して、またはスパイク(spike)とマッチするウィンドウに対して、O(1)時間内の最終ウィンドウを並列に埋めることを可能にする。さらに、さまざまな実施形態では、最終ウィンドウに現れないO(1)内の行を破棄するスマートなバッファリング法を適用する。さらに、さまざまな実施形態が、任意選択で、射影された全ての列を流す(stream)するため、ウィンドウイングされたライン(windowed line)の上に繰返し子(iterator)を生成する。
非限定的なプロセスへの導入として、図1は、一般的なクエリに対する実行フローの概要を示す。クエリ仕様を受け取った後、100で、システムがそのクエリ仕様を分析する。これは、110で、この分析によって選択された方法に従ってデータを離散化することを含むことができる。120で、データに関するヒストグラムを計算する。130で、このヒストグラムを使用して、クエリ仕様によって巻き込まれたデータのウィンドウを分析し、その結果、ウィンドウイングバッファ150、152、154および156をスキャンし、埋めることによって、並列処理するためのデータバッファ140の準備が整う。160で、これらのバッファ結果をマージ(merge)し、表示するウィンドウに対してトリミング(trim)し、ある条件が満たされた場合、170で、必要な場合にのみ、最終ウィンドウに関するローカル並べ替えを実行する。次いでline#繰返し子180を出力する。
(フィルタ/結合演算を用いた列ベースクエリ処理)
概要の項で述べたとおり、列指向(column oriented)エンコードおよび圧縮を大量のデータに適用して、データをコンパクト化し、同時に、データに関する後のスキャン/検索/クエリ操作を実質的により効率的にするためにデータを編成することができる。これに応じて、さまざまな実施形態では一般に、外部クエリ要求を、2つの異なる内部副要求、すなわち指定されたWHERE節およびORDER BY列に対する行の分布についての統計量を計算する第1の内部副要求と、この統計量に基づいて、ウィンドウにマッチする行だけを選択する第2の内部副要求とに分割することによって、これを達成する。この点に関して言えば、本明細書に記載した技法を任意のクエリ用途に対して使用して、エンドアプリケーションまたはエンドユーザへのクエリ結果の送達速度を向上させることができる。すなわち、並べ替えられ、フィルタリングされた行をウィンドウイングする任意の用途が利益を得ることができる。
より詳細には、クエリ要求がストレージ層に到来した後、そのクエリ要求を分析し、そのクエリがORDER BY節またはWHERE節を含まない場合には、SKIPおよびTOPによって指定された物理行を返すことによって、このクエリをストレージに対して直接に解決する。これらの行がフィルタリングされ、かつ/または順序付けされる場合、最初のステップは、ウィンドウの内容の性質を識別するのに役立てるため、統計量を構築することができるかどうかを判定するステップである。
この時点で、実データを含む列に関してそれらの統計量を構築することができるかどうか、または合成(「離散化された」)列に関してそれらの統計量を構築する必要があるのかどうかを判定することもできる。この離散化ステップは、例えばそれぞれのスレッドによって最終ウィンドウ内にいくつの行が生成されるのかを識別することを可能にすることによって、またはデータスパイクに関するウィンドウを生成する間のメモリおよび時間のコストを最小化することによって、例えば並べ替えられた列の中の別個の(distinct)DataIDの数が大きい場合に統計量を構築するコストを最小化すること、またはORDER BYが指定されていないときに並列ウィンドウイング中のメモリ割当てのコストを最小化するのに役立つ。この離散化関数は一般に、順序付けされた列と物理セグメントの関数fn(順序付けされた列,物理セグメント)と見ることができる。
使用することができる離散化のタイプには、同じグループ内の順序付けされた隣接する値をクラスタ化すること、ORDER BYが設定されていないときに、フィルタリングされたデータがWHERE節を通過する場合にセグメントによって離散化すること、およびスパイクを(セグメントごとに)別個のグループに分割することによって離散化するなどが含まれる。離散化関数が存在する場合に、離散化関数が選択されると、次いで、一般に以下のような形態の内部クエリが実行される。
このクエリは、並べ替えられた列上のそれぞれの値の発生数、または、離散化関数がプラグインされている場合には、離散化されたそれぞれの値の発生数を記述する統計量を返す。
それらの結果に対して、例えばx軸が、順序付けされたGroupIDを含み、y軸が、以前のグループの発生の累積和(running sum)を含むヒストグラムを構築することができる。本明細書では用語「和」を時にΣと短縮する。
同じGroupIDへの離散化によって複数のDataIDがマッチすることがあるため、GroupIDを順序付けするのに、存在する全ての行を並べ替える必要があるわけではなく、別個の全てのDataIDを並べ替える必要があるわけではないことに留意されたい。さらに、データを保存するために使用するエンコード法を考慮し、かつ/または予め計算された順序付けされたストア(「階層」)を使用することによって、特定のグループの位置を、それらの値自体を比較することなく決定することができる。
この時点で、最終仮想行セット内のそれぞれのグループの位置を知らせる有用な統計量、例えばヒストグラムデータが取得されたことになる。後に使用するため、任意選択で、この情報をキャッシュに入れることができる。次に、指定されたウィンドウ位置を、ヒストグラム中のデータと比較することができ、並べ替えられた列上のどの値を、目に見えるウィンドウに表示するのかを決定することができる。
これが分かった後、第2の内部クエリを生成する。第2の内部クエリは一般に以下のような形態をとる。
内部的に、複数のスレッド上で並列に実行することができるこのクエリは、最終ウィンドウのトラックを維持するデータキャッシュデータ構造を使用する。このデータキャッシュは、クエリ仕様、渡されたヒストグラム、ウィンドウの位置、使用する離散化のタイプおよび処理に適用する並列性の程度に基づいて、その構成を決定する。したがって、最終ウィンドウを埋める要求は、潜在的に複数のプロセッサ上で並列に実行することができ、この複数のプロセッサはそれぞれ、異なるセグメント(含まれる列の部分)をスキャンし、最終結果セットを部分的に実現する。この点に関して言えば、前述のデータキャッシュ構成に応じたさまざまなバッファタイプを使用することができる。
それらのバッファ内へ挿入はO(1)であり、それらのバッファ間で異なるものはそれらのポリシーである。挿入を実行する方法、および特定のバッファを選択するのかまたは別のバッファを選択するのかの判断は、バッファ構成、ならびにスキャンしている現在のバケット内の内容の純粋さ(purity)/不純さ(impurity)についてのメタデータに基づく(バケットは、含まれるWHEREおよびORDER BY列内の現在スキャンされているフラグメント(fragment)である)。一例として、ORDER BY列上の純粋さについてのこのメタデータを分析することができ、そのバケットの全長の間、ORDER BY処理されている値が変化しない場合には、そのバケット全体に対して、条件を満たすline#を記録する適正なバッファがどのバッファであるのかを決定することができる。あるいは、バケット全体の長さに対してWHERE条件が変化しないことをメタデータが示している場合には、バケット内の全てのラインを同じように処理する(バッファに追加する資格を与え、または与えない)ことができる。
あるタイプのバッファは、クライアントが要求したものは何でも挿入する「通常の」バッファの働きをし、他のバッファは、所与のしきい値後に挿入しようとする一切の試みを破棄し、別のバッファは、循環/リングバッファ方式で既存のレコードに上書きする。それらのバッファによって使用されるサイズおよびポリシーは、データキャッシュが構成される間に選択され、全てのプロセッサをレバレッジしている、すなわち並列実行を使用しているO(n)スキャン時間の間に、最終ウィンドウを埋めることを可能にする。
このクエリの終わりに、1つまたは複数のデータキャッシュ、2つ以上のセグメントおよび2つ以上のプロセッサが使用可能な場合はより多くのデータキャッシュが存在する可能性があり、それらのデータキャッシュは、最終ウィンドウに表示する全てのline#を含み、これは、正確な数よりもやや多くすることもできる。次いで、トリミングを適用する。すなわち、O(1)のうちに、ヒストグラムを使用することによって余分なline#を排除する。多くの場合、line#を保持している残ったレコードは、(セグメントをスキャンする固有の順序のため)自然な順序(natural order)にあるか、または結果を外へ流すときにその場でマルチマージ(multi−merge)することができるため、追加の並べ替えを必要としない可能性がある。それにもかかわらず、例えばクラスタ化によって離散化するために、トリミングされた結果を並べ替えることが依然として必要となる可能性があるいくつかの場合、または、中間バッファに複数の値が割り当てられているが、並べ替えは、目に見えるウィンドウのサイズに限定され、目に見えるウィンドウのサイズに関係するため、この並べ替えのコストが常に、最もコストがかかる場合でさえも、テーブル全体を並べ替えるコストよりも小さいいくつかの場合がある。一般的なウィンドウイングシナリオに関して、目に見えるウィンドウのサイズは、テーブル中で使用可能な行数よりも何桁も小さい。
生成されたウィンドウイング情報は次いで、条件を満たす行(line#)を返す列挙子(enumerator)を使用する外側の層にさらされる。この列挙子は、最終行セットを生成する際の主要なドライバとして使用される。
このように、さまざまな実施形態では、ユーザインタフェースコンポーネントまたは他のインタフェースによって生成されたクエリを処理して、ある種のデータウィンドウを要求し、それらのウィンドウに関するフィルタを適用し、それらのウィンドウを並べ替えることができる。この点に関して言えば、非限定的な一実施態様では、性能を向上させるため、下記のクエリなどのクエリに応答するために、データと要求しているアプリケーションとの間の層として、ウィンドウイングサポート(windowing support)を追加する。
典型的なシナリオでは、データを消費するシステムまたはアプリケーションが、クエリハンドラ/プロセッサとのインタフェースを使用し、このクエリハンドラ/プロセッサは、このデータ消費システムまたはアプリケーションに代わって、クエリを満たすために、データを効率的に探査し、フィルタリングし、並べ替え、データウィンドウを返す。非同期クエリ演算がサポート可能である間、実際のクエリは比較的に高速に完了すると予想される。
例えば、シナリオの一例において、ユーザまたはアプリケーションが10億行を含むテーブルと対峙し、このテーブルに関する問合せをしたいとする。例えば、ユーザは、フィルタを適用し、さらに1つの列によって並べ替えを実施することができる。後に詳細に説明するさまざまな実施形態では、ユーザは、クエリを満たす適当なテータウィンドウを数秒以内に取り出すことができる。ウィンドウが取り出された後、ユーザは、追加のクエリを巻き込むUIコンポーネントを介して、スクロールダウンすることができ、そのときには、わずか0.5秒のうちに1万行の後続のウィンドウが返される。
ある用語(nomenclature)に関して、任意選択で、集計(aggregation)結果を保持するように最適化されたデータキャッシュデータ構造を使用することができる。単純化された例として、座標として、一方の側に販売員のID、もう一方の側に製品のIDを有し、それぞれのセル内に集計値(例えばその販売員が製品を販売した販売の和。販売員および製品はそのセルの座標によって識別される)を保持した2次元アレイとして「スクエア(square)」データキャッシュが編成される。この例において、データキャッシュ内の集計された値に関連付けられた固有の順序はない。
本明細書で使用するとき、クエリカーネル(query kernel)は、集計およびフィルタリングを含み、論理的観点からは、SQLクエリ:SELECT<列>,<集計>FROM<テーブル>WHERE<述語>GROUP BY<列>と等価であるフォーミュラエンジン(formula engine)要求に応答するように最適化されたコンポーネントを指す。クエリカーネルは、データキャッシュを返すように設計される。これは、データキャッシュが、さまざまなコアシナリオに対して上位層が効率的に動作することができる最適な構造であるためである。
本明細書で使用するとき、行セットは、このクエリ処理コンポーネントとのインタフェースを用いて見ることができる項目(item)を含む一組のデータ、複数の行、複数の列を指す。例えば、行セットは、「販売員」によって並べ替えられた行として表された、「販売員」、「製品」および「請求価格」列を含む、全ての販売のリストを含むことができる。行セットは、サーバによって流されることができ、行セットの行は固有の順序を有する。
クエリスペック(query spec)データ構造はクエリを記述し、任意選択で、サーバとストレージの間のインタフェースとして使用することができる。テキストフォーマットで構成されてはいないが、クエリスペックデータ構造は、論理的に、サーバがストレージエンジンに送るクエリと等価であるとみなすことができる。
後により詳細に説明するが、ランレングスエンコード(RLE)は、シーケンス中で値Xが続けてN回現れると言うことによってデータを圧縮する手段である。大量のデータに対するエンコード技法についての補足的コンテキストに関する項で後に説明するパッキングアルゴリズムによる処理時に、RLE圧縮は有利である。RLE圧縮はさらに、データを高速に集計し、高速にフィルタリングするためにクエリカーネルによって実行されるスキャン中にレバレッジされる。これについても、補足的コンテキストの項で後により詳細に説明する。処理中に、列指向ストレージにおいてRLEシーケンスが最大化され、列指向ストレージは、特定の列に同じ値を有する隣接する行のシーケンスを最大にする際に変換される。
限定はされないがSQLクエリなどのクエリがクエリエンジンに渡されると、エンジンは、それらのクエリを解析し、それらのクエリを内部クエリスペックに結合し、そのクエリスペックをクエリハンドラに渡す。クエリハンドラは、並べ替えられ、フィルタリングされたデータの指定されたウィンドウを含む順序付けされた行セットを返す処理を内部的に実行する。
クエリエンジンとクエリハンドラの間の通信のため、標準クライアント−要求インタフェース機構、例えばクエリクライアント要求/応答を使用することができる。渡される要求は、どのデータを返すべきかを記述したクエリスペックを含む。応答は、データキャッシュの代わりに行セットを含む。これは、データキャッシュが固有の順序を有するためである。
図2は、コンポーネントおよび例示的なインタフェースの非限定的な概要ブロック図である。消費側で、インタフェースコンポーネント200は、クエリ202の発行、およびその結果としての行セット(1つまたは複数)204の受取りを処理する。中間層のクエリエンジン210は、クエリ仕様(スペック)212を定義し、クエリハンドラ220のクライアント要求ハンドラ222に渡すことによって、クエリ202を準備することができる。クライアント要求コンポーネントは、クエリスペック212が、高速並べ替えなしアクセスアルゴリズム(fast no sort access algorithm)226にクエリスペック224を転送することを巻き込むのか、または、列ベース並べ替えアルゴリズム240にクエリスペック242を転送することを巻き込むのかを判定する。いずれの場合も、クエリエンジン210に行セット214が返され、インタフェースコンポーネント200へ転送される。前述のとおり、列指向ストレージ、統計量および他のコアサービスコンポーネント230は、要求されたデータに関するヒストグラムの生成などを処理する。列ベース並べ替え240は、クエリスペック238に関して列ベーススキャン234と協力し、任意選択で、ライトデータキャッシュ(light data cache)236を交換に関して使用することができる。他のキャッシュデータ構造232を使用して、後に再使用する一時結果を保存することもできる。高速並べ替えなしアクセス226が使用される場合には、列挙子228が、コアサービスコンポーネント230からの結果を知らせる。
このクエリハンドリングコンポーネントの内部では、ORDER BYをターゲットとする完全に異なるクエリエンジンを提供することから、既存のクエリカーネルを変更し、クエリカーネルの内部での並べ替えに対する直接サポートを追加すること、またはハイブリッド解決手段までのいくつかのオプションが関係する。
この点に関して言えば、クエリが、クエリスペックの形態でクエリハンドリングコンポーネントに到来すると、クエリが調べられ、実行経路が決定される。並べ替えまたはフィルタリングを巻き込まない単純なクエリに関しては、簡単なISAM型のアクセスをストレージに対して直接に使用することができ、より複雑なクエリに関しては、データ分布に留意し、クエリカーネルまたはバケット指向並べ替えアルゴリズムを使用するより複雑な実行計画が選択されることに留意されたい。
キャッシュを使用して、後にユーザがUIコンポーネント内でスクロールする間に再使用することができるコストのかかる中間結果を保存することができる。
10億行に関する並べ替えられた結果を数秒の時間フレーム内に返す要件を満たすのに、力ずくで全てを並べ替える(brute−force−sort−everything)単純な方法は、時間とメモリ使用の両面でコストがあまりにかかりすぎる。
ある種の状況下においてある種のモジュールを再使用し、他のモジュールをスキップするモジュール式の方法が、さまざまな実施形態で使用される。どのモジュールを実行するのかを含む全体実行フローの一般的なアルゴリズムの完全で網羅的な概要が利用可能であり、次に、これについてより詳細に論じる。
最初に、含まれるモジュールの高レベル概要を図3に示す。示されているように、最初に、300で、クエリスペックを分析する。次いで、310で、第1のステップとして、ヒストグラムを計算する。このヒストグラムに基づいて、320で、そのクエリによって巻き込まれるローカルウィンドウ分布を分析し、標準選択330または列ベース並べ替え340を選択して、処理を実行する。いずれの場合も、結果は、350で、要求を出したアプリケーションに返される。
最初に、さまざまなケース/シナリオを提示する。最初に、最も単純な特定のケースを示し、次第により複雑で汎用的(generic)なケースを見ていく。さまざまな実施形態では、統合された汎用的で網羅的なアルゴリズムがモジュール式に提示される。任意選択で、キャッシュを使用して、ある一時結果を、再使用のため保存することができる。
この点に関して言えば、クエリを受け取ると、後に分析するクエリスペックを定義する。クライアント要求がクエリハンドリングコンポーネントに到来したら、このクエリスペックを分析して、並べ替えおよびフィルタリングを一切含まない単純なクエリが含まれるのか、または、そのクエリが、かなりの処理を必要とするクエリであるのかを判定する。
フィルタリングもせず、並べ替えもしないクエリ、例えば索引付き順次アクセス法(ISAM)に関しては、フィルタリングも並べ替えもしない場合、直接ISAM方式型のアクセスを使用することにより、オーバヘッドなしでこの要求を満たすことができる。このことは、(1)含まれる列に関して適正な列挙子を得、(2)正しい位置でGoto()を実行し(例えばSKIPを実行し)、(3)そのデータに関する行セットを構築し、例えばTOP数の行に対してNext()を実行し、その値をデコードし、行セットを埋めることを含意する。この点に関して、一実施形態では、DataIDを変換するためのサーバからクエリハンドラへの往復が不要になるため、DataIDを含む行を返す代わりに、クエリハンドリングコンポーネントのレベルでデコードを実施する。
フィルタリングはするが、並べ替えはしないクエリに関して、これは、より汎用的な「フィルタリングも並べ替えもするクエリ」の並べ替えのない単純化されたケースであり、実行に関する違いは、専用の並べ替え演算が必要ないことであり、データフィルタリングステップを含むが、並べ替えステップを含まず、フィルタに関するウィンドウを返すこの汎用的なケースを使用することができる。
この点に関して、一実施形態では、クエリカーネル、例えば複数の並列ジョブを処理することができるクエリカーネルを使用して、既存のバケット指向フィルタリング論理をレバレッジし、(line#、連続line#)の形の行を含む複数の「ライト」データキャッシュを得、それらにキャッシュに関して、複数のライトデータキャッシュをマージする(Merge−Multi−Light−DataCaches)一般的なアルゴリズムを実行して、実(SKIP,TOP)ウィンドウを見つける。最初のSKIP+TOPウィンドウが既に取り出されたことが分かったら、一部のセグメントジョブをより早く停止することができることに留意されたい。本明細書ではcline#sとも呼ぶ連続line#sは、列ストレージ内で物理的に隣接しており、フィルタ述語にマッチするラインのカウント(count)である。したがって、(line#,cline#−s)フォーマットは、述語にマッチし、連続した形で物理的に保存されているデータのチャンク(chunk)を記述する。それらのチャンクは、列に基づいてデータがコンパクト化されたことの副産物であることがあり、並べ替え演算が実行される列上で自然の(natural)RLEシーケンスが見つかることもある。cline#sは「フィルタリングされた」チャンクを取り扱うため、バケットのRLEレングスはcline#sとは異なることにも留意されたい。
次いで、それらの分割された複数のウィンドウに関して、単純なISAMのケースと同じ方法で行セットを構築することができる。図4は、このプロセスの概要ブロック図である。外部クエリスペック412は、サーバ400のクエリハンドラ410によって処理され、内部クエリスペック435に変換される。
フィルタ述語を含むこのクエリはクエリカーネルに転送され、フィルタとマッチする連続した行のチャンクが、それらが存在する位置とともに得られ、それらのチャンクから、このケースでは並べ替えを実行する必要なしに、「選択された」ウィンドウが計算される。
フィルタリングはしないが、並べ替えはするクエリに関して、これも、より汎用的な「フィルタリングも並べ替えもするクエリ」(後により広範囲に論じる)の単純化されたケースである。この特定のケースでは、実際のフィルタを適用する必要はないが、並べ替えられたデータを出力する必要がある。次いで、値のコンパクト化された列ベースシーケンス460に関して問い合わせるクエリカーネル450によって、このデータが、式440に従ってフィルタリングされる。クエリカーネル450は次いで、フィルタとマッチしたline#および連続line#s(cline#s)を含む行430を返す。前述のとおり、ライトデータキャッシュ425を使用して、行セット出力415を形成するための処理およびマージ420の操作をサポートすることができる。
この点に関して言えば、並べ替えられた列上の分布が、選択される実行計画に影響を及ぼすことに留意されたい。本明細書で実行されるさまざまな効率的なフィルタリングおよび並べ替え演算の単純化された概要は、フィルタ述語がクエリカーネルにプッシュされないことを除いて、汎用的なケースと同じ演算が実行されるということである。ある時点で、(並べ替えられた列のDataID,line#,cline#s)を含む行のチャンクが得られ、これらのチャンクが、前述のより単純なケース(ISAMケースおよびフィルタリングはするが並べ替えはしない(Filtered−but−Not−Sorted)ケース)に対して説明した方法と同じ方法で行セットを構築するために使用される。
大量のデータに関するフィルタリングおよび並べ替えを含むクエリに関しては、クエリが、フィルタまたはORDER BY節を含む場合、その要求を満たす実行計画が決定される。実際の計画は、データのパターンに依存し、その因子には、並べ替えが実行される列上のDataIDの分布および基数(cardinality)が含まれる。以下のセクションでは、これをより詳細に検討し、データの分布およびパターンが実行計画にどのように影響するのかを説明する。
並べ替えられた列の異なるデータ分布に対する実行計画に関して、図5は、遭遇しうる潜在的なデータ分布500、510、520、530のリストである。これらのそれぞれのケース500、510、520、530の処理については、後により詳細に説明する。説明を容易にするためより単純なケースから始めて、より複雑なケースへ一般化する。図5では、x軸に、別個のDataIDがあり、y軸に、DataIDの頻度(重複(duplicate)の数)が示されている。
ケース500は、多くの重複を有する分布、例えば合理的な数の別個のDataIDを有するが、歪んだケース(skewed case)ではない分布を示す。一般に、この分布は、合理的な数の別個のDataIDがあり、それぞれが多数の重複を有し、極端に「歪んだ」ケース(例えば値の半分が単一のDataIDとマッチする)ではないため、このシナリオにおいて「良い(good)」基数として知られている。
ケース500の例は、一様分布、正規分布、またはテーブル内の行の数に比べて別個のDataIDの数が合理的に少ない、すなわち、1<<|別個のDataID|<<|テーブル内の行の数|である他の任意の分布を含むことができる。「良い」基数の一例としては、例えば最大100万個の別個のDataIDを有し、歪んだ分布を持たないテーブルが考えられる。
それらのタイプの分布上にレバレッジすることができる属性は、概して、DataIDが何回も重複し、したがって、それぞれのDataIDに対応する発生数、例えば10億行が存在するが、別個のDataIDは100万個しかないことを記述する統計量(ヒストグラム)を追跡する(track)ことができることである。したがって、並べ替えられたDataIDを発生数とともに保持する、例えば階層処理時間に計算された正確なヒストグラムを実現することができる。
この点に関して、ヒストグラムは「並べ替えられている」ことに留意されたい。その結果、実際のカウントの代わりに、次のDataIDを調べることによってカウントを計算することができる累積和を保持することができる。必要な場合には、逆方向の並べ替え順のために、物質化された(materialized)累積和を実際のカウントから差し引くことによって、逆方向の累積和を計算することができる。累積和の概念をさらに下表Iに示す。
フィルタを適用しないケースでは、この正確なヒストグラムを使用して、フィルタを適用しなかった場合に特定のウィンドウで見ることができる実際のDataIDを(並べ替えられた列から)決定することができる。
例えば、以下のクエリを考える。
上表Iのヒストグラム情報を調べれば、行312および313に対しては「バス」が返され、行314、315、316に対しては「自動車」が返されることが簡単に分かる。
バスおよび自動車を含む正確な行が何なのかに関しては、以下のクエリを実行することによってこれを決定することができる。
これクエリから、ストレージline#sに従って、最後の2つのバスおよび最初の3つの自動車がピックアップされる。
<他の列>の代わりにcline#sを使用し、出力された行セットを流すことに関してより高速である可能性があるSELECTを実行することができるが、関係が含まれない場合、すなわちデータが単一の物理テーブルから到来し、NATURAL JOINがない場合に、これは最もよく機能することに留意されたい。さらに、フィルタが適用される場合には、予め計算されたヒストグラムが一切なくてもこれを実行することができるが、クエリカーネルを使用してある統計量をその場で生み出すことにより、クエリ時にそれが少し遅くなる可能性があることにも留意されたい。
さらなる詳細として、フィルタが適用される場合には、順序付けされたDataIDおよびそれらのカウントを記述したヒストグラムは、フィルタアグノスティック(filter agnostic)であるため十分ではない。したがって、どれが表示される実際の行であるかが決定される。例えば、以下のクエリを考える。
最初に、この述語を直接に評価すべきではない。なぜなら、このクエリカーネルは既に、これを実行するための多くの最適化をその場に有しており、そのため、この述語は、WHERE節を評価するためにクエリカーネルへプッシュされるためである。
次いで以下のような内部クエリが実行される場合には、
車両ごとのマッチのカウントを保持する1座標の「標準」データキャッシュが受け取られる。DataIDが並べ替えられ、それらに関する累積和が維持される。このデータ分布例に関しては、合計で約100万個以上の別個のDataIDが存在し、そのうちの一部は、おそらくフィルタによって除外される。
この時点で、上記の統計量(フィルタリングしないケース)と同じ統計量(ヒストグラム)が得られる。主な違いは、この統計量が次にフィルタリングされた行に適用されることである。フィルタリングしないケースと同じ形式の後続のクエリは、ウィンドウからのDataIDにマッチする行をもたらす。主な違いは、<userが指定した述語>が、以下のように、クエリカーネルにプッシュされて処理されることである。
これは基本的に、統計量、クエリカーネル、およびVertiPaqの副産物である自然の連続したシーケンスをレバレッジする、(SKIP,TOP)ウィンドウを得るための選択アルゴリズムの変形である。フィルタリングされたデータに関するCOUNT()およびRUNNING_SUM()を得る代替法は、階層を知っている列をクエリカーネルにフィードすることであることでありうることに留意されたい。この方法は、後続の並べ替えを回避するが、仮想列を提供する点から実現に手際を要するだけでなく、クエリカーネル実行中に、性能に悪影響を及ぼすと考えられるランダムメモリアクセスが関与する。
図6は、実際の出力ウィンドウを決定するために論理的観点から何が実行されるのかを説明する図である。ヒストグラム610は、処理鎖を通じて効率的な結果620を生成する、上でより詳細に説明したDataID600および累積和602のリストを含む。
DataIDあたりの重複が非常に少ない状況では、別個のDataIDが多数存在するが、歪んだケースは存在しない。例えば、取引IDまたは(例えば多数のDataIDがあり、重複が非常に少ない)何か類似のものによって並べ替えるときのケースのように、別個のDataIDが多数あるケース、例えば10億行のうちの1億行〜10億行が別個のDataIDであるケースを考える。そのケースの分布は、y軸に発生数、x軸に別個の値を示す図7の分布700のように見える。
この状況では、正確なヒストグラムは実現可能ではなく、フィルタリングされたCOUNT()に対してクエリカーネル要求を実行し、巨大なデータキャッシュを得ることも実際的ではない(多数の別個の値→高い基数→大きなデータキャッシュ)。
したがって、このような状況では、離散化法を使用することができる。すなわち、(順序に関して隣接する)連続した一組のDataIDを離散的な対応物にマップし、次いでその離散値に関するヒストグラム(統計量)を構築する。この概念を下表IIに示す。
同時に、表IIIに示すように、GroupIDに関して累積和を計算することができる。
この離散化を使用すると、クエリカーネルからのそれぞれのDataID(SELECT DataID、COUNT()GROUPBY DataID)の正確な発生数に関する統計量を得る代わりに、順序付けされた離散グループ内で、基本的に以下の内部クエリを実行することによって値の発生数を得ることを除き、上記のアルゴリズムと同じアルゴリズムを使用することができる。
これは、最初にある迂回(indirection)レベル(離散化フェーズ(phase))を経ることを除き、適当に(nicely)分散した平均的な数の重複に対する前述のアルゴリズムの一般化であることに留意されたい。より具体的には、データが適当に分布したケースとはちょうど、離散化が実際に1→1であり、DataID==GroupIDである(1つのグループが正確に1つの値を有する)特定のケースである。
このクエリカーネルがGroupIDに対してどのように機能することができるかに関して、GroupIDは、(DataIDだけを処理することができる)クエリカーネルの外側の概念であるため、1つの一般的な解決策は、外部キー(FK)→主キー(PK)に対して「プロキシ(proxy)」列が機能するのと同じように、セグメントクエリに「仮想」列をフィードすることである。この仮想列は、実際の現在のストレージ行DataIDに対応するGroupIDを返す。
10億個のDataIDが存在する場合によく適した別の解決策では、10億の別個のDataIDが、ストリングではなく、数に対応し、それらを「値によってエンコードする」ことができる。この解決策は、10億の別個の数を保持する列に対してはよく機能するが、10億の別個のストリングを保持する列に対しては機能しない。
DataID→GroupIDを解くためのルックアップ中のクエリカーネル内でのランダムメモリアクセスを意味する10億の別個のストリングの場合に関しては、少なくとも、そのデータセットを介して階層にアクセス可能である場合には、group#を識別するのにDataIDの位置だけで十分であるため、離散グループを計算するときに、ストリング比較は必要ない。1つの解決策は、値によってエンコードするときだけでなく、ハッシュによるエンコードするときにも、「if v1>v2→did1>did2」属性を強制することである。これを実行する間、強制にはコストが伴い、このコストは、クエリ時にではなく処理時に支払われる。さらに、この方法は、(did>v1 AND did<v2のようなものをバイパスする)ORスライス(OR slice)を使用したときにクエリカーネル性能を向上させることができること、ならびに階層繰返し子を「非物質化(dematerialize)」し、pos=did−XM_DATA_ID_NULLのような合成関数を有することによって階層繰返し子を改良することを含む、別のいくつかの利点を有すると考えられる。
基本的に、値によるエンコードは、関数f:value→DataIDを使用し、この関数に対しては以下の属性が維持され、
DataIDが別のDataID(NULLに対するDataIDを除く)よりも小さい場合には逆になり、この場合には、値も同じように順序付けされる。
このことは、DataIDの相対的な順序が、並べ替えられた値の相対的な順序と一致することを意味し、隣接するDataIDは隣接する並べ替えられた値に対応するため、隣接するDataIDをグループ化することができる。ランダムメモリアクセスを必要としない1つのグループ化戦略は、DataIDをGroupIDにマップする単純な関数g:DataID→GroupIDを適用することによって、(Min−DataID...Max−DataID)内の別個のDataIDの空間全体を、比較的に等しい(数値)区間(interval)に分割することである。
他のグループ化アルゴリズムおよび戦略は、ヒストグラムに基づくものとすることができる。設定する境界については、後にデータパターンの判定について述べるときに説明する。
この離散化はしたがって、DataIDの空間を、GroupIDのより小さな空間に圧縮すること、およびDataIDの空間が、GroupIDのそれぞれの発生に対してより多く重複を有すること可能にし、それにより、この問題は、適当に分散したDataIDのケースに関して上で解決した問題に変化する。
図8に例示的に示すように、DataIDのグループ800に関する統計量810をクエリカーネルから得た後、以下の形のクエリを実行する。
ここで、統計量から得られる累積和に関してSKIP/TOPウィンドウのマッチングを実行し、それに対する行が出力される実際の候補GroupIDを受け取る。
この候補GroupID(例えばG#12、G#13、G#14)は、候補DataIDのリストに拡張される。
(既に論じた値によるエンコード関数の属性のため)値によるDataIDに対して、選択されたDataIDをフィルタリングする追加の述語を、(より高速なクエリカーネル評価を可能にするために)以下のように書き直すことができるので、これは有益である。
この場合の結果は、データ分布のよりいっそう極端なケースに対して後に説明する並べ替えアルゴリズムを容易に適用するのに適した一組の特殊な「ライト」データキャッシュである。
このタイプのデータパターンに対するcline#sは、追跡(tracking)を必要としない可能性があり、列ベース並べ替えの代わりに、DataIDの連続したチャンクを知らない標準並べ替えアルゴリズムを使用することができることに留意されたい。その理由は、cline#sの追跡は、ほとんど全てが==1であるときに、不必要なオーバヘッドとなるためである。理論上の変曲点は、フィルタリングされたDataIDの連続したチャンクの平均値がcline#s>4であるときであるが、実用上の限界はおそらくこれよりも少し高い。任意選択の一実施形態では、述語の選択性(selectivity)および/または並べ替えられた列の平均RLEランに基づいて、この値を推定することができる。
DataIDが少数で、重複が10億あるスパイクを有するデータ分布の状況に関して、10億個の一組の行にまたがる[性別]列に対するデータ分布を考える。この点に関して言えば、図9のサンプル分布900に示すように、それぞれが5億個の重複を有する2つの別個のDataIDを示す統計量が得られる。ウィンドウがたまたま端にある場合には、10億の全ての行を並べ替える必要がある。たとえ、一方の別個のDataIDだけが選択されたウィンドウ内にあると判定された場合であっても、それは依然として、フィルタがない場合、またはフィルタの選択性が、ほとんど全てが含まれるようなものである場合に、その行を要求している後続のクエリが、5億行を有するデータキャッシュを返すことを意味する。
データのこのパターン対してレバレッジすることができる1つの属性は、スパイクを有するそれらのDataIDがおそらく、RLEの形に圧縮されることである。このことは、並べ替えが実行される列がおそらく、長いRLEランを有することを意味する。そのため、やはりフィルタが存在しない場合には、行ごとに並べ替える代わりに、列ベース並べ替えに従ってRLEシーケンスを並べ替えることができる。RLEの能力のため、これは、桁違いに高速になると予想される。
しかしながら、フィルタが適用される場合には、出力されるセット内に一部の行が含まれない可能性があるため、直接にRLEシーケンスに基づいて並べ替えを実行することはできない。この場合には、cline#s(述語を通過した行の連続したチャンク)を得るために、特殊なクエリカーネル要求が生成され、並べ替えは、cline#sを追跡している間に、複合キー(DataID,ストレージ−line#)に関して実行され、この追跡は、いくつの行が、述語とマッチする並べ替え列上に不変のDataIDを有する有効な行であるかを指示する。
図10は、実行されるものの論理図である。RLEエンコードされた男性および女性データに関して、下記のクエリなどの内部クエリが送られる。
応答として、クエリカーネルの見地からデータキャッシュが返されるが、内部的には、集計をサポートする必要がなく、やはり後により詳細に説明するように、フィルタを通過した、連続したラインのチャンクの列ベース並べ替えを含む次の演算に対してより良好にフィットする特殊な「ライトデータキャッシュ」(後に詳述する)が組み込まれる。
次に、歪んだデータ分布に関して、これは、10億の別個のDataIDが存在し、その一部は固有だが(決して重複しないが)、それでも重複した5億個の値を有するあるDataID、例えばスパイクを有するDataIDを有する最も汎用的なケースを表す。
図11に示した分布の一例110は、10億個のレコードを有するテーブルを含み、その列上の値の半分はNULLであり、残りの半分は、ほとんど完全に重複しない個のDataIDである。例えば、あるデータベースは、それぞれの従業員の住所を有することがあり、それらの住所は固有である傾向があるが、従業員の半分に対するレコードデータがないこともあり、したがって、値「Don′t have address data」(住所データなし)が何回も重複する。
この場合、(離散化を使用して)10億の別個のDataIDをターゲットとする解決策は、スパイクを処理する困難を有し、スパイクを有するケースをターゲットとし、不変のDataIDの長く連続したランを利用する解決策は、全く重複を持たないDataIDに関するウィンドウを処理する困難を有する。基本的に、cline#−sに気を配ることができるが、そのフィルタにマッチする行の全てのシーケンスは、それら自体の別個のDataIDを有し、したがってcline#sに気を配るオーバヘッドは不要である。
このような場合、方法は、データの「ローカル」分布に対して適当な実行計画を使用することである。このケースでは、大域的なデータ分布は重要ではなく、要求されたデータの特定のウィンドウに対してデータがどのように分布しているかの方が重要である。これを図12に示す。クエリおよびウィンドウがスパイクを巻き込む場合、スパイクを有するデータアルゴリズムを適用することができる。一様分布部分が巻き込まれる場合、離散化技法を適用することができる。
これを達成するためには、この場合も、ヒストグラムおよび統計量を集める。分布ヒストグラムを計算するため、サンプリングを実行して、スパイクを見つける。この点に関しては、適当な実行戦略を選択するために、データの一般的なパターンを知ることが望ましい。要求されたウィンドウに対するある候補DataIDが「スパイク」に含まれることが分かっている場合には、例えば>重複が100万または他のしきい値よりも大きいか否かを推定する。
(DataIDが非常に少数の重複を有し、それらを一緒のグループに分けたいときに)離散化を実行するケースでは、順序付けされた隣接するDataIDのグループをどのように分割するか、すなわちそれぞれのバケットにいくつ含まれるのかを推定する。1つの方法は、別個のDataIDの最小−最大空間全体を等しい区間に分割し、固定された区間サイズに依存する非常に高速なDataID←→GroupID変換をそれぞれのグループに対して使用する方法である。
このために、必要ならば、ヒストグラムを構築することができ、これは、処理時またはクエリ時に実行することができる。このヒストグラムは、例えば無作為に抽出すること、または1/1000程度の値をチェックし、次いでそのヒストグラムを空間全体に広げることに基づくことができる。(1/1000の比率では、10億行は単に100万ランダムメモリアクセスであるため、)このヒストグラムは、比較的に速い時間で構築することができるはずである。
このデータに関する無作為抽出はさらに、所与のDataIDがスパイクであるか否か、例えば1,000,000個の標本が抽出され、DataIDが半分の時間で見つかるかどうかを知らせる。「スパイクを有する」DataIDのこのリストを追跡することができ、10億行に対して、別個の値は100個未満であるはずである。さらに、並べ替えを実行する判断を下す前に、ウィンドウがこのDataIDを含むか否かを、cline#sに基づいて、またはcline#sに基づかずに(例えば全てのDataIDが別個である場合)調べることができる。
VertiSortまたは列ベース並べ替えに関して、10億個の行に関する並べ替えを実行するため、(並べ替えられ、かつ/またはフィルタリングされた列上のRLEシーケンス/バケットを利用して)データが、値の列ベースシーケンスに従ってVertiPaq処理されまたはコンパクト化にされることがレバレッジされることは、歪んだ分布の議論の際に既に述べた(ただしこれは、他の大部分のケースでも当てはまる)。
この点に関して言えば、(クエリカーネルが、データだけでなく、フィルタリングされたDataIDの連続したチャンクについてのメタ情報をも返すようにすることによって)内部(ストレージ)RLEレングスを知ることにより、並べ替えプロセスを、それらのRLEレングスを使用して最小化することができる。したがって、値が変化しない10億の行が存在する場合には、たとえそれらがフィルタによってチャンクに分割される場合でも、返されたデータキャッシュに関する物理的な並べ替えは必要ない。
これを実現するために、A)データだけではなく、メタデータも返すようにクエリカーネルに何らかの変更を加え(実際にはこれは、特殊なデータキャッシュ内の連続したラインの集計を実行することによって、力ずくで実行することもできるため、不必要なスキャンを回避するバケット処理レベルでの最適化である)、B)(DataID)→(line#,cline#s)(line#,cline#s)...を追跡することができ、並べ替え演算の複雑さを、n*log(n)(nは行数)からm*log(m)(mは、ウィンドウ内の別個のDataIDの数)へ低減することを可能にする、特殊な「ライトデータキャッシュ」を実現することができ、かつ/またはC)同じプロセッサによって異なるセグメントに対して再使用されたデータキャッシュの高速インプレースマージ(fast in−place merge)、ならびにクエリカーネルによって生成された全ての「ライトデータキャッシュ」が集計される最終ステップ中の高速マルチマージを可能にする、「ライトデータキャッシュ」の特殊な集計を実現することができる。
図13は、並べ替えられたデータに関するウィンドウを生成する際に含まれるコンポーネントのスタックの代表的な図である。これは、サーバ1340によって受け取られ、クエリハンドラ1350によって処理されるクエリスペック1300を含み、クエリハンドラ1350は、line#、cline#および累積和を含む、フィルタリングされたデータに関するインデックス1360を生成することができる。この点に関して、処理鎖のボトムアップ(bottom up)に続いて、列ベーススキャン1320の適用中に列ベースコンパクト化1330がレバレッジされる。前述のとおり、列ベーススキャン1320とともに、ライトデータキャッシュを使用することができるが、このライトデータキャッシュは集計を実行しない。最後に、列ベース並べ替え1310からの結果セットが、クライアントに返す行セット1302として表現される。
この点に関して言えば、示されているとおり、長いRLEシーケンス(例えば性別)に対するフィルタの適用が、連続したDataID(cline#s)のチャンクを返すことがある。しかし、それらは、フィルタリングされた連続したデータを表す仮想チャンクである。したがって、(DataID,line#)を複合キーとして使用し、cline#を追跡することによって、(DataID,line#,cline#s)の並べ替えを実行することができる。
フィルタ演算によって、RLEチャンクを、以下のような形にフラグメント化することができることにも留意されたい。
最終ビュー(view)内のストレージラインの順序を保持することが望ましいため、たとえそれらの間にギャップがあったとしても、同じDataIDに対応するline#−sを連結することができ、それらは、以下のような形を有することができる。
ここまでで、(最終ウィンドウ内に見える別個のDataIDだけを並べ替え)、実際のラインを並べ替えない並べ替えははるかに高速になる。
並べ替えた後、それらの結果を、WHERE節に固有のインデックスとして集計することができ、インデックスは累積和も追跡する。例えば、Line#は保持されるが、cline#は、累積和から推論することができるためもはや必要ではない。
したがって、このインデックスのフォーマットを、(line#,累積和)を含むテーブルと見ることができる。なお、このインデックスは、WHERE節に固有であり、任意選択でキャッシュに入れることができる。キャッシュに入れる場合には、圧縮のため、および、後に、キャッシュに入れられたWHEREに、より制限的なAND節が適用される場合に、このデータをクエリカーネルにフィードバックするために、そのキャッシュを物理的なストレージテーブルとして維持することに価値があることがある。
cline#sおよび「ライトデータキャッシュ」に対するクエリカーネルサポートに関して、選択並べ替えのためのある統計量(例えばフィルタリングされたデータに関するGROUPBY)を得るために、クエリカーネルを使用することができ、クエリカーネルは、DataIDが含まれることを知った後に、フィルタリングされた実際の行を得るために使用される。
しかし、行自体は出力されず、その代わりに、バケット指向並べ替えアルゴリズムを実行するのに役立つ(DataID,line#,cline#)を使用する。
(DataID,line#,cline#)の形の行を要求しているクエリのためにline#、cline#を得ることに関して、(DataIDの代わりに)line#を返すある仮想列をフック(hook)することができ、クエリカーネルはラインを得るためにある仮想機構を使用するため遅くなることはあるが、それぞれのラインをカウントすることによって「ライトデータキャッシュ」内での集計を達成することができ、または、偽(fake)の列全体を物質化することができるが、ラインはそれぞれ異なるline#を有するため、これはさらに、スキャン/バケット化(bucketization)の純粋さを破壊することになろう。フィルタとマッチする実際のline#(cline#)をカウントするため、別の「偽の」(しかし純粋な)列が使用されることになる。これも遅くなるが、この場合には、常にPure()値を返すライトエヌメレータ(LightEnumerator)をシミュレートすることができる。
より高速な解決策は、(line#,cline#)を特殊なデータキャッシュへ出力するための論理を、クエリカーネルに追加することであろう。
この場合のクエリカーネル内のバケットプロセッサは、バケットごとに述語を評価するが、それぞれのマッチに対してWHERE節があれば、
WHEREが純粋であり、並べ替えられた列に対するバケットが純粋である場合には、
a.並べ替えられた列の純粋な(DataID)を、DC座標として、
b.バケットが始まるline#を、DC座標として、
c.バケットサイズ(cline#)を、集計された測度(measure)として
データキャッシュに送る必要があり、
WHEREが純粋であり、並べ替えられた列に対するバケットが不純であるか、または
WHEREが不純であり、並べ替えられた列に対するバケットが純粋であるか、または
WHEREが不純であり、並べ替えられた列に対するバケットが不純である場合には、
a.並べ替えられた列の現在のDataIDを、DC座標として、
b.マッチする行が見つかったline#を、DC座標として、
c.(cline#)を、集計された測度(measure)として
データキャッシュに送る必要がある。
行のSKIP+TOP#が(セグメントからの)フィルタによって受け入れられた後は、そのウィンドウに対してそれ以上のデータは必要ないことが分かっているいくつかのケース(例えば並べ替えられていないが、フィルタが適用されたデータ)を除き、SKIP+TOPマッチ後の停止は任意選択である。データはどのみち出力されないため、この内部要求に対して、より高速に停止し、データをそれ以上スキャンしないように、セグメントクエリを構成することができる。その時点で、列ベーススキャンを停止することができる。
ライトデータキャッシュに関して、クエリカーネルから得られた(DataID、line#、cline#)データに対する集計は実行されないが、そのデータは、並べ替えの準備ができていなければならない。そのために、標準データキャッシュを使用する代わりに、実際の集計を実行することはできないが、並べ替えを容易にする形で(DataID、line#、cline#)を累積する専用の「ライト」データキャッシュを、クエリカーネルにフックすることができる。
クエリカーネルの点からは、データキャッシュは(論理的に)、表されたセル1400を有する図14のように見える。離散化の場合には、図14のDataIDはGroupIDに置き換えられることに留意されたい。
実際は、同じ(line#,DataID)座標にはヒットせず、加算は不要である(同じDataIDを含むクロスセグメント行のある合体(coalescing)を実行することができるが、line#は実際に異なるため、これは「標準の」加算とは異なる)。
所与のセグメントに関して、クエリカーネルは、低いline#から高いline#へデータを順番にスキャンすることが分かっており、そのため、line#は(セグメントの境界において)昇順である。これは、line#が「予め」並べ替えられることを意味する。
高速並べ替えのため、1次並べ替えキー=DataID、2次並べ替えキー=ストレージ−line#に基づいて、別個のDataIDが追跡され、所与のセグメント内の連続した(line#,cline#s)のシーケンスも追跡される。
それぞれのセグメントに対するハッシュ(DataID)→(line#,cline#s)の順序付けされたシーケンスを使用して、これを達成することができる。最後に(マルチマージフェーズ中に)、(seg#1<seg#2)の場合には、seg#1内の全てのラインがseg#2内のラインの前にあるため、O(1)時間内の異なるセグメントに由来する順序付けられたシーケンスを照合することができる。
物理的に、それぞれのセグメントに対して、このハッシュは、line#、cline#対によって記述された値を指すキー:DataID1500を有する図15のようなものを有する。チャンクのシーケンスに関連した増大するメモリのために、インクリメンタル(incremental)ポリシーまたは推定ベースのポリシーに対するインクリメンタルアロケータ(allocator)を使用することができる。
DataID、または離散化が適用される場合にはGroupIDの実際の並べ替えに関して、(値によるDataIDが使用される場合、GroupIDが使用される場合、または階層情報が使用可能な場合には、)実際の値を見る前に、ウィンドウ内の別個の値の並べ替えを実行することができる。
ライトデータキャッシュのマージに関して、クエリカーネルに由来する複数の「ライト」データキャッシュを、内部要求の結果として得ることができる。これは、実際に、クエリアグリゲータ(Query Aggregator)が、複数のプロセッサ上で複数のセグメントクエリ(セグメントにつき1つ)をスケジュールするためであり、最終的には、プロセッサの数までの別個のデータキャッシュを生成することができる。
最終フェーズの間に、セグメント内の全てのline#が、別のセグメント内の全てのラインよりも大きいか、または小さいという属性を利用することによって、O(m)時間内の複数のハッシュを高速にマージすることができる(m=見えるウィンドウ内の別個のDataID)。この属性は、所与のDataIDに対してチャンクのリストの合体がうまくいくことを意味する。
最終インデックスの構築に関して、これは基本的に、WHERE節、SORT列および(通常、歪んだ)DataIDのセットに依存するインデックスである。
最終クエリカーネル結果から、最も汎用的なケースでは以下のデータが得られる。
(DataID)→(line#,cline#s),(line#,cline#s),(line#,cline#s)...
これは、並べ替えられていない複数のデータキャッシュが並べ替えられ、続いてマルチマージされた上記のステップで並べ替えられた。次いで、以下のデータが得られ、
(並べ替えられたDataID)→(line#,cline#s),(line#,cline#s),(line#,cline#s)...
これから、以下のインデックスが構築される。
(line#、累積和)
line#は、クエリカーネルから来たときのストレージ行番号である。
累積和は、(SKIP,TOP)ウィンドウが位置する仮想line#を与える。このインデックスをキャッシュに入れることもでき、これにより、ライトデータキャッシュを構築するためにデータを再スキャンすることを回避することができ、スキャンが十分に高速になることがある。
出力された行に関して、クエリハンドリングコンポーネントコード経路と行セットを出力する関連UIコンポーネントは同じ機構を使用することができる。プロデューサ(producer)としての(line#,chunk#)が追加されたクエリスペック(選択された列)および直接にデコードされた行に基づいて生成された行セットが出力される(対応するラインからDataIDを得、辞書(dictionary)を調べて、結果を行に入れる)。したがって、ISAM型のアクセスはちょうど、(line#,chunk#)に対する単一の(SKIP,TOP)値だけが追加されるアクセスの特定のケースである。
実行フローに関して、一実施態様では、モジュール法が使用される。
図16は、クエリスペック分析モジュール(Analyze Query Spec Module)のプロセスフローを示す。開始1600の後、1610で、並べ替えが指定されており、1630で、ヒストグラムがまだキャッシュに入れられていない場合、1640で、ヒストグラムを計算する。ヒストグラムがキャッシュに入れられている場合には、1660で、ローカルウィンドウ分布を分析する。1610で並べ替えが指定されていない場合には、1620で、フィルタが指定されているかどうかを判定する。フィルタが指定されている場合、フローは1630へ進む。フィルタが指定されていない場合には、1650で、行セットを決定し、出力する。
図17は、ヒストグラム計算モジュール(Compute Histogram Module)のプロセスフローを示す。ステップ1710は、離散化が必要かどうかを判定する。離散化が必要な場合には、1720で、エンコードが値によるかどうかを判定する。エンコードが値によらない場合には、1730で、階層が使用可能であるかどうかを判定する。階層が使用可能でない場合、実行できることはほとんどなく、処理は遅くなる可能性がある。1710で、離散化が必要でない場合には、GroupID=DataIDであり、フローは、統計量を得る1740へ進み、1750で、GroupIDに基づいて統計量を並べ替え、累積和を計算する1760。任意選択で、1770で、ヒストグラムをキャッシュに入れることができ、最後に、1780で、ローカルウィンドウ分布を分析する。同様に、1720で、エンコードが値によると判定された場合には、GroupID=DataID/区間であり、フローはやはり1740へ進む。1730で、階層が使用可能な場合には、GroupID=階層位層(Hierarchy Position)(DataID)/区間であり、フローはやはり、上で説明した1740へ進む。
図18は、ローカルウィンドウ分布分析モジュール(Analyze Local Window Distribution Module)のプロセスフローを示す。1800で、候補GroupIDを識別する。1810で、候補DataIDを識別する。次いで、1820で、クラスタ化されたDataIDが予想されるかどうかを判定する。クラスタ化されたDataIDが予想される場合には、1840で、列ベース並べ替え技法を適用する。クラスタ化されたDataIDが予想されない場合には、1830で、標準選択アルゴリズム1830を使用する。
図19は、標準選択アルゴリズムモジュール(Standard Selection Algorithm Module)のプロセスフローを示す。1900で、候補(DataID,Line#)を選択する。1910で、これらの候補を複合キーによって並べ替える。1920で、ヒストグラムを使用して(SKIP,TOP)ウィンドウを計算する。最後に、1930で、行セットを出力する。この点に関して言えば、これは標準選択アルゴリズムであり、このアルゴリズムは、非常に少ない重複(または連続したチャンク)、例えばDataIDあたり平均4未満の連続した重複が予想されるデータに関して、巨大なウィンドウ、例えばTOP100万行+が返されることが予想される場合に有用である。このケースでは、オーバヘッドが利益よりも大きいため、連続したチャンクcline#sを追跡する価値はない。
図20は、後によりいっそう詳細に説明するVertiSort選択モジュール(VertiSort Selection Module)のプロセスフローを示す。2000で、インデックスがキャッシュに入れているかどうかを判定する。インデックスがキャッシュに入れられている場合には、フローは2060までスキップし、ヒストグラムおよびインデックスを使用して(SKIP,TOP)ウィンドウを計算する。インデックスがキャッシュに入れられていない場合には、2010で、(DataID,Line#,Cline#s)を含むライトデータキャッシュを参照する。2020で、DataIDを(Line#,Cline#s)と照合する。2030で、別個のDataIDを並べ替える。2040で、インデックス(line#,累積和)を計算する。2050で、インデックスをキャッシュすることができ、フローはやはり2060へ進み、ヒストグラムおよびインデックスを使用して(SKIP,TOP)ウィンドウを計算する。最後に、2070で、行セット結果を出力する。
行セット出力モジュール(Output Rowset Module)に関して、一実施形態では、指定されたline#−sの選択された(潜在的には複数の)チャンクに基づいて、XMQueryRowsetが生成され、行セットは、クライアント要求結果の一部としてサーバに返される。
フィルタリングされた結果に関するヒストグラムおよびインデックスをキャッシュに入れることに関して、「並べ替えられた統計量」は、どの物理行が、(所与のフィルタおよび並べ替え順に対して)見られるデータの1つ(または任意の)ウィンドウに対応するのかを記述する。したがって、現在の要求を満たし、(計算するコストが小さいため場合には)このインデックスを破棄し、またはこのインデックスをキャッシュに入れ、後に、例えばユーザが、スクロールダウンし、並べ替え順をASCからDESCに切り換え、新たなデータ列を追加し、新たなANDまたはOR節を追加するときなどに、再使用することができる。
キャッシングは任意だが、キャッシングは、同じ結果を再計算することを省き、特に同じクエリに関するスクローリング時に性能を向上させることができる。例えば、(line#,累積和)レコードを保持したフィルタリングされたデータに関するインデックスを節約することができる場合には、2回のクエリカーネル内部要求が回避される。
さらに、キャッシングは、ユーザを含むシナリオにおいて、既存のWHEREに、より制限的な(AND)節を追加するのに役立つ。このシナリオでは、(line#,累積和)スーパーセットを含むキャッシュに入れられた(不完全)マッチングインデックスを取り出すことができ、クエリカーネルに、(列ストレージ中に配置された)このデータから来るline#sをフィードすることができ、追加のWHERE節だけが渡される(より高速なクエリカーネル評価)。
キャッシュに入れられた(line#,累積和)インデックスは、実際のDataIDを保存する必要はなく(すなわちいかなる種類の粒度(granularity)が指定されず)、したがって、選択において他の列を含むが、同じWHERE節を有するクエリに対する一切の追加のコストなしで、それらを再使用することができる。
正確なキャッシュヒット(cache hit)が得られた後、キャッシュに入れられたline#−sおよび行数からデータのウィンドウを構成することによって、例えば累積和に対してデルタ(delta)を計算することによって、XMQueryRowsetを生成することができる)。さまざまなキャッシングポリシーを使用することができ、これには例えば、UIシナリオに対する使用パターンについての専用の知識を使用して、キャッシュ内における生存期間を決定すること、スケジューラ(scheduler)からの統計量およびテンプ(temp)構造のメモリコストからの統計量を使用して、インデックスの値を決定すること、立ち退き(eviction)中のインデックスのコスト値f(CPUコスト/メモリ使用)を使用して、キャッシュ内における生存期間を決定すること、インデックスのコスト値f(CPUコスト/メモリ使用)を使用して、項目をキャッシュに入れるか否かを判定することなどが含まれる。
このように、一般的な方法を説明した。これを図21に示す。2110で、ローカルウィンドウに適用するデータのサブセットを取り出すため、データに関するフィルタ演算および/または並べ替え演算を巻き込むアプリケーションからクエリを受け取る。2120で、そのクエリの指定された任意のWHERE節および/またはORDER BY列に対する行の分布についての統計量を計算する。2130で、これらの統計量に基づき、ローカルウィンドウとマッチする、1つのフィルタ演算および/または並べ替え演算に対する結果セットを決定する。2140で、結果セットをアプリケーションに送信する。
図22は、要求しているクライアントの視点から見た流れを示す。この点に関しては、2210で、ローカルウィンドウに適用するデータのサブセットを取り出すため、データに関するフィルタ演算および/または並べ替え演算を巻き込むアプリケーションからクエリを送信する。2220で、前述の統計ベースの分析に基づいて結果セットを返す。2230で、結果を得る際に使用した1つまたは複数の結果または中間構造をキャッシュに入れることができる。
(列ベースデータエンコードに関する補足的コンテキスト)
概要の項で述べたとおり、さまざまな実施形態において、列指向エンコードおよび圧縮を大量のデータに適用して、データをコンパクト化し、同時に、データに関する後のスキャン/検索/クエリ操作を実質的により効率的にするためにデータを編成することができる。さまざまな実施形態では、ウィンドウイングされたデータに関する統計量を決定し、要求されたウィンドウに関連する結果の計算中にそれらの統計量をレバレッジすることによって、複雑なフィルタ演算および/または並べ替え演算を巻き込む大量のデータに関するクエリのケースに、効率的な演算を適用することができる。
例示的で非限定的な実施形態では、生データを、列ごとに1つの値シーケンスを有する一組の値シーケンスに列化(columnize)した後に(例えばデータ列のフィールドを直列化(serialize)した後に、例えば、全ての姓を1つのシーケンスとして直列化し、または全てのPO Order#sを別のシーケンスとして直列化するなどした後に)、データを「整数化(integerize)」して、辞書エンコードもしくは値エンコードに従って、または辞書エンコードと値エンコードの両方に任意の順序で従って一様に表された整数シーケンスを、列ごとに形成する。この整数化ステージは、一様に表された列ベクトルを与え、特にテキストストリングなどの長いフィールドがデータに記録される場合に、単独でかなりの節約を達成することができる。次に、全ての列を調べて、圧縮ステージが、任意の列のランに、列ベクトルセット全体の全体サイズ節約量が最も大きくなるランレングスエンコードを繰り返し適用する。
前述のとおり、このパッキング技法は列ベースであり、優れた圧縮を提供するだけでなく、圧縮技法自体が、コンパクト化された整数列ベクトルがクライアント側に送達された後に、データを高速に処理するのに役立つ。
非限定的なさまざまな実施形態では、図23に示すように、大規模データストレージ2300をコンパクト化し、さらに、データに関する結果として生じるスキャン/検索/クエリ操作を実質的により効率的にする、列ベースエンコーダ/コンプレッサ(compressor)2310が提供される。データ処理ゾーンCのデータ消費装置2320によるクエリに応答して、コンプレッサ2310は、このクエリに関連する圧縮された列を、データ伝送ゾーンBの伝送網(1つまたは複数)2315を介して送信する。このデータはインメモリストレージ(in memory storage)2330に送達され、したがって、データ処理ゾーンCのデコーダおよびクエリプロセッサ2340によって、関連する列の圧縮解除を非常に高速に実行することができる。この点に関して言えば、クエリに関連する圧縮解除された列によって表される行に、効率的な処理の追加の層のため、バケットウォーキング(bucket walking)が適用される。繰返しの操作が一緒に実行されるように、バケットウォーキング中には行の類似性が利用される。後により詳細に説明するが、大量のウェブトラフィックデータまたはトランザクションデータなどの実世界サンプルデータにこの技法を適用すると、196Gb RAMを有する標準または商品サーバでは、サーバデータのクエリ/スキャンが、従来システムの能力を天文学的に超える毎秒約1.5テラバイトデータの速度、および大幅に低減したハードウェアコストで達成される。
圧縮することができるデータのタイプは特定のデータタイプに一切限定されず、莫大な量のデータの大規模スキャンに依存するシナリオも同様に無数にあり、リアルタイムビジネスインテリジェンス用途におけるビジネスデータまたはビジネスレコードにこれらの技法を適用する商業上の重要性は疑いえない。この圧縮技法によって達成されるクエリ処理速度のとてつもない向上により、リアルタイムリポーティングおよびトレンド識別は全く新しいレベルに移行する。
エンコーダの一実施形態の全体を図24に示す。この実施形態では、2400で、生データを受け取り、またはストレージから読み込み、この時点で、エンコード装置および/またはエンコードソフトウェア2450が、2410で、データを列として編成する。2420で、列ストリームを、一様なベクトル表現に変換する。例えば、整数エンコードを適用して、名前または場所のような個々のエントリを整数にマップすることができる。このような整数エンコード技法は、2×〜10×の因子でデータを減らすことができる辞書エンコード技法とすることができる。これに加えて、またはこれの代わりに、値エンコードはさらに、1×〜2×のサイズ低減を提供することができる。これは、2420で、列ごとに整数のベクトルを残す。このような性能の向上は、コンパクト化されているデータの影響を受けやすく、したがって、このようなサイズ低減の範囲は、単に非限定的な推定値として与えられ、異なるステップの相対性能についてのおおまかな見当を与える。
次いで、2430で、エンコードされた一様な列ベクトルをさらにコンパクト化することができる。一実施形態では、全ての列を横切って最も頻度の高い値または値の発生を決定するランレングスエンコード技法を適用し、その場合には、その値に対してランレングスが定義され、このプロセスは、例えばその列内で少なくとも64回の発生を有する繰り返し発生する整数値に対して、ランレングスエンコードの利益がかろうじて得られる点まで繰り返される。
他の実施形態では、この繰返しプロセスのそれぞれのステップで、ランレングスエンコードを適用することによるビット節約を調べ、再順序付けおよびランレングスの定義の適用によって、それらの列の中で最大のビット節約を達成する列を選択する。言い換えると、目標は、できるだけ少ないビットで列を表すことであるため、それぞれのステップで、最も大きな節減を提供する列のビット節約を最大にする。この点に関して言えば、ランレングスエンコードは、かなりの、例えば単独で100×以上の圧縮の向上を提供することができる。
他の実施形態では、2430で、ビットパッキングとランレングスエンコードの組合せを使用するハイブリッド圧縮技法を適用する。これらの2つの技法の潜在的な節約を調べる圧縮分析を適用し、例えばランレングスエンコードが与える正味のビット節約が不十分であるとみなされる場合には、列ベクトルの残りの値にビットパッキングを適用する。したがって、1つまたは複数の基準に従って、ランレングスによる節約が最低限であると判定されると、列の残りの比較的に珍しい値に対して、アルゴリズムはビットパッキングに切り替わる。例えば、列中に表された値が比較的に珍しい値になった場合(珍しくないまたは繰り返し出現する値が既にランレングスエンコードされた場合)には、ランレングスエンコードの代わりに、ビットパッキングをそれらの値に対して適用することができる。2440で、出力は、前述の技法に従ってエンコードされ、圧縮された、列値に対応する一組の圧縮された列シーケンスである。
一実施形態では、消費クライアントシステム上のメモリに、前述の技法に従って圧縮された列がロードされると、それぞれの列C1、C2、C3、C4、C5、C6を横切ってそのデータをセグメント化して、図25に示すようなセグメント2500、2502、2504、2506などを形成する。この点に関して言えば、それぞれのセグメントは数億以上の行を含むことがあるため、並列化は、例えばクエリに従ってデータを処理しまたはスキャンする速度を向上させる。それぞれのセグメントを別々に処理している間に、それぞれのセグメントの結果を集計して、結果の完全セットを形成する。
図26は、上記の方法の全体を、生データ2600の入力から始まる流れ図に従って説明する。2610で、前述のとおり、生データ2600の列に従って、データを再編成する。これは、従来のシステムのようにレコードのそれぞれのフィールドを一緒に維持するとは対照的である。例えば、図27に示すように、それぞれの列が、シーケンスC2701、C2702、C2703、C2704、C2705、C2706などの独立したシーケンスを形成する。例えば、このデータが小売取引データである場合には、列C2701が製品価格のストリングであり、列C2702が購入日のストリングを表し、列C2703が保管位置を表し、...ということがありうる。この列ベース編成は、コンピュータシステムによって集められる大部分の実世界データは、表される値に関してそれほど多様ではないことを考慮して、データ型内において固有の類似性を維持する。2620で、この列ベースデータを1回または数回の変換にかけて、一様に表された列ベースデータシーケンスを形成する。一実施形態では、ステップ2620が、それぞれの列を、辞書エンコードおよび/または値エンコードによって、データの整数シーケンスに低減させる。
2630で、ランレングスエンコードプロセスおよび任意選択のビットパッキングを用いて、この列ベースシーケンスを圧縮する。一実施形態では、ランレングスエンコードプロセスが、全ての列のうち、最も大きな圧縮節約を達成する列の列データ値シーケンスを再順序付けする。したがって、ランレングスエンコードが最も大きな節約を達成する列を再順序付けして、ランレングスエンコードによって置き換えられている共通の値をグループ化し、次いで、再順序付けされたグループに対してランレングスを定義する。一実施形態では、ランレングスエンコードアルゴリズムを、それらの列を横切って繰り返し適用して、ステップごとにそれぞれの列を調べ、最も大きな圧縮節約を達成する列を決定する。
ビット節約が不十分である、または節約がしきい値よりも小さいなど、1つまたは複数の基準に従って、ランレングスエンコードを適用する利益がかろうじて得られ、または最低限になると、それを適用する利益は対応して小さくなっていく。その結果として、アルゴリズムを停止することができ、または、それぞれの列内のランレングスエンコードによってエンコードされていない残り値に対してビットパッキングを適用して、それらの値に対するストレージ必要量をさらに低減させることができる。組合せにおいて、ハイブリッドランレングスエンコードとビットパッキング技法は、列シーケンス、特に有限のまたは限られた数の値がその中に表されている列シーケンスを低減させるのに、非常に効果的であることがある。
例えば、フィールド「性別」は、2つのフィールド値:男と女だけを有する。ランレングスエンコードを用いると、データが、前述のように生データの列ベース表現に従ってエンコードされている限りにおいて、このようなフィールドを非常に単純に表すことができる。これは、背景の項で説明した行に焦点を合わせた従来の技法が、事実上、それぞれのレコードのフィールドを一緒に保持することによって、列データの共通性をバラバラにするためである。「21」などの年齢値のとなりの「男」値は圧縮されず、「男」または「女」値だけのとなりの「男」値も圧縮されない。このように、データの列ベース編成は、効率的な圧縮を可能とし、プロセスの結果は、一様に表され、コンパクト化された一組の別個の列ベースデータシーケンス2640である。
図28は、実際のデータに基づく列化プロセスの一例を示す。図28の例は、4つのデータレコード2800、2801、2802および2803に対するものだが、本発明は、数テラバイトのデータに適用することができるため、これは説明を単純にするためである。一般的に言って、コンピュータシステムによってトランザクションデータが記録されるとき、そのデータは、一般にレコードを受け取った時間順に、1レコードずつ記録される。したがって、そのデータは、事実上、それぞれのレコードに対応する行を有する。
図28では、レコード2800が、値「Jon」2811を有する名前フィールド2810、値「555−1212」2821を有する電話番号フィールド2820、値「jon@go」2831を有するeメールフィールド2830、値「21st St」2841を有する住所フィールド2840、および値「Wash」2851を有する州フィールド2850を有する。
レコード2801は、値「Amy」2812を有する名前フィールド2810、値「123−4567」2822を有する電話番号フィールド2820、値「Amy@wo」2832を有するeメールフィールド2830、値「12nd Pl」2842を有する住所フィールド2840、および値「Mont」2852を有する州フィールド2850を有する。
レコード2802は、値「Jimmy」2813を有する名前フィールド2810、値「765−4321」2823を有する電話番号フィールド2820、値「Jim@so」2833を有するeメールフィールド2830、値「9 Fly Rd」2843を有する住所フィールド2840、および値「Oreg」2853を有する州フィールド2850を有する。
レコード2803は、値「Kim」2814を有する名前フィールド2810、値「987−6543」2824を有する電話番号フィールド2820、値「Kim@to」2834を有するeメールフィールド2830、値「91 Y St」2844を有する住所フィールド2840、および値「Miss」2854を有する州フィールド2850を有する。
行表現2860が、再編成された列表現2870に列化されると、それぞれが5つのフィールドを有する4つのレコードを有する代わりに、それらのフィールドに対応する5つの列が形成される。
したがって、列1は、名前フィールド2810に対応し、値「Jon」2811、値「Amy」2812、値「Jimmy」2813および値「Kim」2814をこの順に有する。同様に、列2は、電話番号フィールド2820に対応し、値「555−1212」2821、値「123−4567」2822、値「765−4321」2823および値「987−6543」2824をこの順に有する。列3は、eメールフィールド2830に対応し、値「jon@go」2831、値「Amy@wo」2832、値「Jim@so」2833および値「Kim@to」2834をこの順に有する。次に、列4は、住所フィールド2840に対応し、値「21st St」2841、値「12nd Pl」2842、値「9 Fly Rd」2843および値「91 Y St」2844をこの順に有する。そして列5は、州フィールド2850に対応し、値「Wash」2851、値「Mont」2852、値「Oreg」2853および値「Miss」2854をこの順に有する。
図29は、本明細書に記載された実施形態によって使用される辞書エンコードの非限定的な一例を示すブロック図である。都市の一般的な列2900は、値「Seattle」、「Los Angeles」、「Redmond」などを含むことができ、このような値は、何度も繰り返されることがある。辞書エンコードでは、エンコードされた列2910が、値ごとの固有の整数など、それぞれの別個の値に対する記号を含む。したがって、テキスト「Seattle」を何度も表現する代わりに、はるかにコンパクトな整数「1」が保存される。よりしばしば繰り返される値は、最もコンパクトな表現(最小ビット、ビット中の最小変化など)へのマッピングを用いて列挙することができる。値「Seattle」は、辞書2920の一部としてエンコード中に依然として含まれるが、「Seattle」は、何回も表現するのではなしに、1度だけ表現すればよい。エンコードされた列2910のストレージ節約は、辞書2920によって巻き込まれる追加のストレージをはるかに上回る。
図30は、本明細書に記載された実施形態によって使用される値エンコードの非限定的な一例を示すブロック図である。列3000は、販売量を表し、フロートストレージを巻き込む、小数を含む一般的なドルおよびセント表現を含む。ストレージをよりコンパクトにするため、値を、フロート値ではなく、より少ないビットで保存できる整数で表すために、値エンコードでエンコードされた列3010は、10の因子、例えば102が適用された値を有することができる。同様に、変換を適用して、値を表す整数の数を減らすこともできる。例えば、2,000,000、185,000,000など、ある列に対して一貫して100万で終わる値を全て106で割って、それらの値を、よりコンパクトな2、185などの表現にすることができる。
図31は、本明細書に記載された実施形態によって使用されるビットパッキングの非限定的な一例を示すブロック図である。列3100は、辞書エンコードおよび/または値エンコードによって整数化された発注量を表すが、それらの値を表すために、1行あたり32ビットが確保されている。ビットパッキングは、セグメント内の値に対してできるだけ少数のビットを使用するように努める。この例では、値590、110、680および320を表すために10ビット/行を使用することができ、これは、列3110を形成するためにビットパッキングを適用した最初の層に比べて相当な節約である。
ビットパッキングはさらに、共通の10(または他の数)のべき乗を除去して、パックされた第2の列3120を形成することができる。したがって、この例のように値が0で終わる場合、それは、発注量を表すために使用している3ビット/行が必要なく、ストレージ構造が7ビット/行に低減されることを意味する。辞書エンコードと同様に、このビット節約は、使用した10のべき乗が何であるかなど、データを列3100に復元するために必要なメタデータによって増大するストレージを大きく上回る。
パックされた第3の列3130を形成するためのビットパッキングの他の層として、68のような値を表すために7ビット/行が必要であることは認識することができるが、最も小さな値は11であるため、範囲を11だけずらす(それぞれの値から11を差し引く)ことができ、そうすると最も大きな数は68−11=57になり、26=64の値が可能なため、57は、6ビット/行で表すことができる。図31は、パッキング層の特定の順序を示しているが、これらの層を異なる順序で実行することができ、あるいは、これらのパッキング層を選択的に除去し、またはこれらのパッキング層に、知られている他のビットパッキング技法を追加することもできる。
図32は、本明細書に記載された実施形態によって使用されるランレングスエンコードの非限定的な一例を示すブロック図である。示されているように、値が繰り返されているため、注文のタイプを示す列3200などの列を、ランレングスエンコードを用いて効果的にエンコードすることができる。列値ランテーブル3210は、注文のタイプを、その注文のタイプに対するランレングスにマップする。テーブル3210のメタデータの表現の対するわずかな変異は許されるが、基本的認識は、ランレングスエンコードが、100のランレングスに対して×50の圧縮を与えることができるということであり、これは一般に、同じデータセットに対してビットパッキングが提供することができる利益よりも優れている。
図33は、技法を合成して、エンコード/圧縮スキームのさまざまな実施形態に統合した、本明細書に記載された一実施形態の全体ブロック図である。生データ3300を、列編成3310に従って列ストリームとして編成する。辞書エンコード3320および/または値エンコード3330が、前述のそれぞれのサイズ低減を提供する。次いで、ハイブリッドRLE/ビットパッキングステージで、圧縮分析3340が、列を横切る潜在的なビット節約を調べ、それによりランレングスエンコード3350を適用するのか、またはビットパッキング3360を適用するのかを判定する。
図33を、図34の流れ図に拡張する。3400で、固有の行表現に基づく生データを受け取る。3410で、このデータを列として再編成する。3420で、辞書エンコードおよび/または値エンコードを適用して、データを初めて低減させる。3430で、前述のハイブリッドRLE/ビットパッキング技法を適用することができる。3440で、圧縮され、エンコードされた列ベースデータシーケンスを保存する。次いで、クライアントが、この圧縮され、エンコードされた列ベースデータシーケンスの全てまたはそのサブセットについて問い合わせたときに、3450で、関係する列を、要求しているクライアントに送信する。
図35は、ハイブリッド圧縮技法の圧縮分析を実行する例示的な方法のブロック図である。例えば、列3500から、値の発生頻度または個々のランレングスの発生頻度を表すヒストグラム3510を計算する。ランレングスの利益が最低限である可能性がある回数の少ない値の再発生に対しては、ランレングスエンコードが適用されないように、任意選択で、しきい値3512を設定することができる。あるいは、またはそれに加えて、ビット節約ヒストグラム3520は、値の発生頻度を表すだけでなく、ハイブリッド圧縮モデルの圧縮技法のうちのどちらか一方を適用することによって達成されるであろう全体ビット節約をも表す。さらに、ランレングスエンコード技法を適用するには、そうすることの利益があまり十分ではない線を引くために、任意選択で、しきい値3522を適用することができる。その代わりに、列のそれらの値に対してビットパッキングを適用することができる。
さらに、任意選択で、列3500のランレングスエンコードを適用する前に、列3500を再順序付けして、最も類似した値の全てを、再順序付けされた列3530としてグループ化することができる。この例では、これが、ランレングスエンコードのためにAを一緒にグループ化し、ビットパッキングのためにBを残すことを意味する。これは、頻度も、または全体ビット節約も、2つのB値に対してランレングスエンコードを適用することを正当化しないためである。この点に関して、これらの残りの列に再順序付けを適用して、レコードデータをロックステップ(lock step)に維持することができ、または、ランレングスエンコードの再順序付けを取り消して元に戻す方法を、列固有のメタデータを介して記憶することができる。
図36は類似の例を示し、この例では、類似列3600に圧縮分析が適用されるが、ハイブリッド圧縮分析によると、2つのB値の正味のビット節約の方がより大きいため、10個のA値の前であっても、2つのB値に対してランレングスエンコードを実行することが正当化されるように、ランレングスの置換えあたりのビット節約が変更されている。この点に関して、異なる料理が盛られた10枚の異なる皿から選ぶ大食家(glutton)によく似て、ランレングスエンコードの適用は、ステップごとに、全ての列を横切るサイズ低減の最も大きな利益を繰り返し追求する点で、「貪欲(greedy)」である。図35と同様に、前述のようにランレングスエンコードを適用するのか、またはビットパッキングを適用するのかについての判定を実施するため、頻度ヒストグラム3610および/またはビット節約ヒストグラム3620のデータ構造を構築することができる。さらに、RLEを実行するのか、またはビットパッキングを実行するのかを判断するときに、任意選択のしきい値3612および3622を使用することもできる。再順序付けされた列3630は、ランレングスエンコードが、より長いランレングスを定義し、したがってより大きなランレングス節約を達成するのに役立つことができる。
図37は、全ての列を横切って、それぞれのステップで最も大きなビット節約がどこで達成されるのかを調べ、任意選択で、ランレングス節約を最大にするために、ランレングス節約を最大にするそれらの列を列3730、3732などとして再順序付けすることを含むことができる、ランレングスエンコードの「貪欲な」態様を示す。ある時点で、値が比較的に珍しい値になるため、ランレングス節約が比較的に小さくなることがあり、この時点で、ランレングスエンコードは停止される。
ハイブリッド実施形態では、残りの値の範囲にビットパッキングを適用する。これを図38に示す。この点に関して、ハイブリッド圧縮技法を適用すると、再順序付けされた列3800は、RLE部分3810と、ビットパッキング部分3820とを含み、これらはそれぞれ一般に、繰り返し発生する値および比較的に珍しい値に対応する。同様に、再順序付けされた列3802も、RLE部分3812とBP部分3822とを含む。
図39に示す一実施形態では、ハイブリッドアルゴリズムが、ビットパッキングによるビット節約およびランレングスエンコードによるビット節約を計算し3900、次いで、3910で、ビットパッキングによるビット節約とランレングスによるビット節約とを比較し、または、3920で、ビットパッキングによるビット節約とランレングスによるビット節約とを調べて、どちらの圧縮技法がビット節約を最大にするのかを判定する。
前述のエンコード技法および圧縮技法の例示的な性能は、実世界データサンプル4001、4002、4003、4004、4005、4006、4006、4007および4008に対して達成することができる約9×から99.7×までの範囲のかなりの向上を示し、この向上はとりわけ、特定の大規模データサンプル内における値の相対的な繰返し量に依存する。
図41は、本明細書のさまざまな実施形態で説明した列化、エンコードおよび圧縮プロセスの最終結果を示すブロック図である。この点に関して、列C1、C2、C3、...、CNはそれぞれ、ランレングスエンコードが適用された繰り返された等質(homogeneous)な値を有するエリアと、図中に「Others」または「Oth」と標識された、列中の異質(heterogeneous)な値のグループを表す別のエリアとを含む。凡例に示されているように、ランレングスによって定義された繰り返された同一の値を有するエリアは純粋(pure)なエリア4120であり、変化に富む(variegated)値を有するエリアは不純(impure)なエリア4110である。この点に関して、人の眼が列を「下方へたどる」と、本明細書で論じた圧縮技法の固有の利益として、そのデータに関する新たなビューが出現する。
全ての列を横切って、不純なエリア4110と純粋なエリア4120の間の最初の遷移点で、または純粋なエリア4120と不純なエリア4110の間の最初の遷移点で、バケットが、最初の行から遷移点の行までの行として定義される。この点に関して、バケット4100は、列を下って、点線によって示された遷移点ごとに定義される。バケット4100は遷移間の行によって定義される。
図42は、特定の行を横切る純粋なエリアの数および不純なエリアの数に基づいてバケットに対して定義される名称を示す。純粋バケット4200は、不純なエリアを持たないバケットである。シングル不純バケット4210は、そのバケットの行を横切って不純なエリアを1つ有するバケットである。ダブル不純バケット4210は、そのバケットの行を横切って不純なエリアを2つ有するバケットである。トリプル不純バケットは不純なエリアを3つ有するバケットであり、以下同様である。
したがって、例示的なデータロードプロセスの間に、データは、後の効率的なクエリに適した表現でエンコードされ、圧縮され、保存され、セグメント内のデータ分布を捜し、ビットパッキングよりも頻繁にRLE圧縮を使用することを試みる圧縮技法を使用することができる。この点に関して、RLEは、圧縮とクエリの両方に関して以下の利点を提供する:(A)RLEは一般に、必要なストレージがビットパッキングよりもかなり少なくてすみ、(B)RLEは、Group By、フィルタリングおよび/または集計などのクエリビルディングブロック演算を実行する間に、データ範囲を通して効果的に「早送りする(fast forward)」能力を含む。このような演算は、数学的に、列として編成されたデータに関する効率的な演算にすることができる。
非限定的なさまざまな実施形態では、1つの列セグメントを一度に並べ替えてから、その同じセグメント内の他の列を並べ替える代わりに、圧縮アルゴリズムが、データの行を、それらの分布に基づいてクラスタ化し、そのようなものとして、セグメント内のRLEの使用を増大させる。本明細書で使用する場合、用語「バケット」は、行のクラスタを記述するために使用され、疑いを回避するため、明確に定義されたOLAP(online analytical processing)およびRDBMSの概念である用語「パーティション(partition)」とは異なると考えるべきである。
データ分布は歪んでおり、多量のデータでは一様分布はまれにしか存在しないと認識されるため、以上に論じた技法は有効である。圧縮用語において、算術符号化(Arithmetic Coding)は、全体としてより少ないビットを使用することを目的として、頻繁に使用される文字をより少ないビットを使用して表し、まれにしか使用されない文字をより多くのビットを使用して表すことによって、これをレバレッジする。
ビットパッキングでは、ランダムアクセスをより高速にするため、固定サイズのデータ表現を利用する。しかしながら、本明細書に記載した圧縮技法はさらに、より頻繁な値に対してより少ないビットを使用する方法を提供するRLEを使用する能力を有する。例えば、原テーブル(説明を単純にするために1つの列「列1」を含む)が以下のようである場合、
圧縮後、列1は、以下のようになり、ランレングスエンコードを適用する第1の部分と、ビットパッキングを適用する第2の部分とに分割される。
上記のテーブルから分かるとおり、最も共通する値100の発生はRLEに縮約され、まれにしか現れない値は、これまでどおりビットパックされた固定幅のストレージに保存される。
この点に関して、データパッキングの前述の実施形態は、以下の2つの別個のフェーズを含む:(1)バケット化を決定するためのデータ分析、および(2)バケット化されたレイアウトに従うためのセグメントデータの再編成。次に、これらのフェーズをそれぞれ、例を挙げてより詳細に説明する。
バケット化を決定するためのデータ分析に関して、目標は、RLEを有するセグメント内のできるだけ多くのデータをカバーすることである。そのため、このプロセスは、「より厚い」列、すなわち、クエリの間により頻繁に使用される列ではなく、大きな基数を有する列に有利な方向へ歪む。使用ベースの最適化を適用することもできる。
別の単純な例を示すため、説明を容易にするために、以下の小さなテーブルを使用する。実際には、このようなテーブルを圧縮しても利益にならない傾向があるため、このような小さなテーブルは一般に、前述の圧縮の範囲には含まれない。さらに、このような小さなテーブルが一般に含まれないのは、圧縮が、エンコードを実行した後に実行され、一実施形態では、値自体ではなくDataIDentification(ID)とともに機能するためである。したがって、説明のため、さらに列「行番号」を追加する。
これらの列を横切って、セグメントデータ内の最大の空間を占める単一の値を見つけることによって、バケット化プロセスは始まる。図18および19に関して前に述べたとおり、これは、それぞれの列に対する例えば以下のような単純なヒストグラム統計量を使用して、実行することができる。
この値を選択した後、そのセグメント内の行を、この値の全ての発生がシーケンスとして起こるように論理的に再順序付けして、RLEランの長さを最大にする。
一実施形態では、同じ行に属する値が全て、それぞれの列セグメントの同じインデックスに存在する。例えば列1[3]と列2[3]はともに3番目の行に属する。このことが保証されると、アクセスごとにマッピングテーブルを使用する回り道のコストを招くことなく、同じ行の値への効率的なランダムアクセスが提供される。したがって、貪欲なRLEアルゴリズムまたはハイブリッドRLE/ビットパッキングアルゴリズムを適用する本明細書に記載された実施形態では、1つの列内の値を再順序付けすると、これは、他の列セグメント内の値も同様に再順序付けされることを含意する。
上記の例では、この時点で、2つのバケット{1,2,4,6,7}および{3,5}が存在する。前述のとおり、本明細書で適用するRLEは貪欲なアルゴリズムであり、このことは、このアルゴリズムが、大域的な最適を見つけることを望んでステージごとに局所的な最適を選択するメタヒューリスティック(metaheuristic)な問題解決に従うことを意味する。最も大きなバケットを見つける最初のフェーズの後、次のフェーズは、次に大きなバケットを選択し、そのバケット内でこのプロセスを繰り返すことである。
それに応じて行を再編成したとき、その時点で、3つバケット{2,7}、{1,4,6}、{3,5}が存在する。最も大きなバケットは第2のバケットだが、そこに値の繰返しはない。第1のバケットは全ての列がRLEランを有し、残りの値は固有である。そのため、列1においてこれ以上RLE利得は得られないことが分かる。バケット{3,5}を考慮すると、RLEに変換することができる別の値1231がある。興味深いことに、1231は、直前のバケットにも出現し、そのバケットを再順序付けして、1231が一番下になり、次のバケットの最上位とマージする準備が整うようにすることができる。次のステップは以下のようになる。
上記の例では、この時点で4つのバケット{2,7}、{6,4}、{1}、{3,5}が存在する。このデータをこれ以上低減させることができないため、プロセスは、セグメントデータを再編成する次のフェーズに移る。
冒頭の例では、性能上の理由から行も再順序付けしたが、それぞれの列セグメント内のデータを再順序付けする操作からのバケットの決定は、純粋に統計量に基づくことができる。それぞれの列セグメント内のデータを再順序付けする操作は、使用可能なコアに基づき、ジョブスケジューラを使用して並列化することができる。
前述のとおり、前述の技法を小さなデータセットに対して使用することは実際的でない。顧客データセットに対して、前述の技法はしばしば何万ものステップを経ることがあり、これに時間がかかることがある。このアルゴリズムの貪欲な性質のため、大部分の空間節約は、最初の数ステップで達成される。数千のステップのうちの最初の2ステップで、節約される大部分の空間は既に節約されている。しかしながら、圧縮されたデータのスキャン側で観察されるとおり、たとえごく小さな圧縮利得であってもクエリ中に報酬を得るため、パックされた列内にRLEが存在すると、クエリの間に性能がかなり向上する。
1つのセグメントは一度に処理されるため、複数のコアを使用して、データ源からセグメント内へデータを読み込むのにかかる時間と、直前のセグメントを圧縮するのにかかる時間とをオーバラップさせることができる。従来の技術では、リレーショナルデータベースから約100,000行/秒の速度で読み取ると、8M行のセグメントでは約80秒かかり、これは、このような作業に対して使用可能なかなりの量の時間である。任意選択で、一実施形態では、次のセグメントに対するデータが使用可能になったら、直前のセグメントのパックも停止することができる。
(列ベースデータエンコードの処理)
前述のとおり、列ベースエンコードに対するさまざまな実施形態に従ってデータを編成する方法は、メモリ内の選択された数の列に対して処理を非常に高速に実行することができる場合に、データの消費側での効率的なスキャンに役立つ。前述のデータパッキング技法および圧縮技法は、行エンコード中に圧縮フェーズを更新し、スキャンは、このインテリジェントエンコードをレバレッジするクエリオプティマイザ(query optimizer)およびプロセッサを含む。
このスキャンまたはクエリ機構を使用して、ビジネスインテリジェンス(BI)クエリに対する結果を効率的に返すことができ、このスキャンまたはクエリ機構は、前述のデータパッキング技法および圧縮技法によってクラスタ化されたレイアウトが生成されるように設計され、RLEの使用が増大するように最適化される。例えば、クエリ処理時、クエリに対して使用されるかなりの数の列が、RLEを使用して既に圧縮されていることが予想される。さらに、この高速スキャンプロセスは、列ストアを横切る行方向(row−wise)クエリプロセッサの代わりに、列指向クエリエンジンを導入する。そのため、(RLEデータと対照をなす)ビットパックされたデータを含むバケットでさえ、データの局所性(locality)による性能の向上は、かなりのものになりうる。
前述のデータパッキング技法および圧縮技法ならびに効率的なスキャンを導入することに加えて、非常に効率的な方法:クエリ内の「OR」スライスおよび関係が指定された複数のテーブル間の「Join」で以下のことをサポートすることができる。
前述のとおり、スキャン機構は、セグメントが、あるセグメントを横切って延び、「純粋」RLEランまたは「不純」RLEランビットパックストレージ内に列値を含むバケットを含むことを前提としている。
一実施形態では、あるセグメントに対してスキャンが呼び出され、キーは、一度に1つのバケットを処理することである。バケット内で、スキャンプロセスは、クエリ仕様に応じて、列指向処理を複数のフェーズで実行する。最初のフェーズは、どの列エリアが純粋で、どのエリアが不純であるのかについての統計量を集めることである。次に、フィルタを処理し、続いてGroup BY演算を処理し、続いてプロキシ列を処理することができる。次に、別のフェーズとして、集計を処理することができる。
以前に述べたとおり、本明細書に記載されたスキャンに対する実施形態は、従来のシステムのような行指向クエリ処理ではなく、列指向クエリ処理を実現することに留意されたい。したがって、これらのそれぞれのフェーズ対して、実行される実際のコードを、(1)操作されている列が、ランレングスエンコードされているか否か、(2)ビットパッキングに対して使用される圧縮のタイプ、(3)結果は疎(sparse)なのか、または密(dense)なのかなどに対して特定的(specific)とすることができる。集計に関しては、(1)エンコードタイプ(ハッシュまたは値)、(2)集計関数(和/最小/最大値/カウント)など、追加の事項が考慮される。
したがって、スキャンプロセスは一般に、さまざまな標準クエリ/スキャン演算子4300からのクエリ結果が全てのバケット行の関数である図43の形態に従う。事実上、クエリ/スキャン演算子4300は、フィルタ、Group By、プロキシ列および集計が複数のフェーズで互いに別個に処理されるような態様で、数学的に分割することができる。
この点に関して言えば、処理ステップごとに、4310で、バケットの純粋さの違いに基づき、バケットウォーキングプロセスに従って演算子が処理される。その結果として、一般化されたコストのかかる全バケット行のスキャンの代わりに、本明細書に記載されたエンコードおよび圧縮アルゴリズムの働きによって、異なるバケットの特殊化(specialization)が導入され、したがって、その結果は、純粋バケット、シングル不純バケット、ダブル不純バケットなどの処理を集計したものになる。
圧縮アーキテクチャのこの能力は、処理数学が単純な演算になるため、純粋バケット対して実行される処理が最も速く、次いでシングル不純バケットが速く、以降の不純バケットでは順に遅くなるため、図44は、バケットのサンプル分布および圧縮アーキテクチャの能力を示す。さらに、意外に多くのバケットが純粋バケットであることも分かった。例えば、図44に示すように、クエリによって巻き込まれる6つの列に関して、それぞれの列の純粋さが約90%である場合(これは、データが似ていることにより、値の約90%がランレングスエンコードで表されることを意味する)、バケットの約60%は純粋バケット、約1/3はシングル不純バケット、約8%はダブル不純バケットであり、残りは1%にすぎない。純粋バケットの処理が最も高速であり、シングル不純バケットおよびダブル不純バケットの処理も依然としてかなり高速であるため、3つ以上の不純なエリアを有するバケットの「より複雑な」処理は最小限に留まる。
図45は、サンプル「filter by column」クエリビルディングブロック4502、サンプル「Group by Column」クエリビルディングブロック4504、サンプル「Aggregate by Column」クエリビルディングブロック4506などのいくつかのサンプル標準クエリビルディングブロックを有するサンプルクエリ4500を示す。
図46は、列選択性による追加の帯域幅低減態様を示すブロック図である。サンプルクエリ4600を見ると、全ての列4620のうちわずか6つの列4610だけが巻き込まれ、したがって、クエリを非常に効率的にするためには、6つの列だけをローカルRAMにロードすればよいことが分かる。
このように、本明細書ではさまざまな実施形態を説明した。図47は、データをエンコードする一実施形態を示し、この実施形態は、4700で、データの異なるデータフィールドに対応する値の一組の列ベースシーケンスに従ってデータを編成することを含む。次いで、4710で、この値の一組の列ベースシーケンスを、辞書エンコードおよび/または値エンコードなどの少なくとも1つのエンコードアルゴリズムに従って、値の一組の列ベース整数シーケンスに変換する。次いで、4720で、この一組の列ベース整数シーケンスを、この一組の列ベース整数シーケンスを横切って適用される貪欲なランレングスエンコードアルゴリズム、またはビットバッキングアルゴリズム、あるいはランレングスエンコードとビットパッキングの組合せを含む少なくとも1つの圧縮アルゴリズムに従って圧縮する。
一実施形態では、この整数シーケンスを分析して、ランレングスエンコード(RLE)圧縮を適用するのかまたはビットパッキング圧縮を適用するのかを判定する。これには、RLE圧縮のビット節約をビットパッキング圧縮に対して分析して、最大ビット節約がどこで達成されるのかを判定することが含まれる。このプロセスは、最大ビット節約がどこで達成されるのかを判定する際に役立てるため、ヒストグラムを生成することを含むことができる。
他の実施形態では、図48に示すように、ビットパッキング技法が、4800で、値の整数シーケンスのうち、あるデータ列を表す部分を受け取ること、およびビットパッキングによる潜在的な低減の3つのステージを含む。4810で、データフィールドを表すために必要なビットの数に基づいて、データを低減することができる。4820で、整数シーケンスの前記部分の値を横切って共有するべき乗数値(numerical power)を除去することによって、データを低減することができる。4830で、整数シーケンスのある範囲にまたがる部分の値をずらすことによって、データをさらに低減することができる。
図49の流れ図に示す他の実施形態では、クエリに応答して、4900で、データの異なる列に対応する値のエンコードされ圧縮された整数シーケンスとして、データのサブセットを取り出す。次いで、4910で、このデータサブセットの値のエンコードされ圧縮された整数シーケンスのいずれかで生じた圧縮タイプの変更に基づいて、このデータサブセットにまたがる処理バケットを定義する。次に、4920で、クエリ処理を効率的にするため、処理されている現在のバケットのタイプに基づいてクエリ操作を実行する。これらの操作はメモリ内で実行することができ、マルチコアアーキテクチャで並列化することができる。
異なるバケットは、(1)シーケンスを横切るバケット内の値の異なる部分が全て、ランレングスエンコード圧縮に従って圧縮され、純粋バケットを定義するバケット、(2)1つを除く全ての部分がランレングスエンコードに従って圧縮され、シングル不純バケットを定義するバケット、または(3)2つを除く全ての部分がランレングスエンコードに従って圧縮され、ダブル不純バケットを定義するバケットを含む。
改良されたスキャンは、特に最も純粋なバケットに対して、さまざまな標準クエリおよびスキャン演算をはるかに効率的に実行することを可能にする。例えば、バケットウォーキング技法が適用され、バケットタイプに基づいて処理が実行されるとき、論理ORクエリスライス演算、関係が指定された複数のテーブル間のクエリ結合演算、フィルタ演算、Group By演算、プロキシ列演算または集計演算は全てより効率的に実行することができる。
(例示的なネットワーク環境および分散環境)
本明細書に記載した列ベースエンコードおよびクエリ処理のさまざまな実施形態は、コンピュータネットワークの一部として、または分散コンピューティング環境内で展開し、任意の種類のデータストアに接続することができる任意のコンピュータまたは他のクライアントないしサーバ装置とともに、実施することができることを当業者は理解することができる。この点に関して言えば、本明細書に記載したさまざまな実施形態は、任意の数のメモリまたはストレージユニットを有し、任意の数のアプリケーションおよびプロセスが任意の数のストレージユニットを横切って起こる任意のコンピュータシステムまたはコンピュータ環境において実施することができる。これには、限定はされないが、ネットワーク環境または分散コンピューティング環境内に展開され、リモートまたはローカルストレージを有するサーバコンピュータおよびクライアントコンピュータを含む環境が含まれる。
分散コンピューティングは、コンピューティング装置およびコンピューティングシステム間の通信交換によって、コンピュータ資源およびコンピュータサービスの共有を提供する。これらの資源およびサービスは、ファイルなどのオブジェクトに対する情報、キャッシュストレージおよびディスクストレージの交換を含む。これらの資源およびサービスはさらに、ロードバランシングのための複数の処理ユニットを横切る処理パワーの共有、資源の拡張、処理の特殊化などを含む。分散コンピューティングは、クライアントがその総体的なパワーをレバレッジすることを可能にするネットワーク接続性を利用して、その企て全体に利益を与える。この点に関して言えば、さまざまな装置が、本明細書の開示のさまざまな実施形態のうちの任意の実施形態の1つまたは複数の態様を実行するために協力することができるアプリケーション、オブジェクトまたは資源を有することができる。
図50は、例示的なネットワークコンピューティング環境ないし分散コンピューティング環境の概略図である。この分散コンピューティング環境は、コンピューティングオブジェクト5010、5012など、およびコンピューティングオブジェクトまたは装置5020、5022、5024、5026、5028などを備え、これらは、アプリケーション5030、5032、5034、5036、5038によって表されたプログラム、方法、データストア、プログラマブルロジックなどを含むことができる。オブジェクト5010、5012など、およびコンピューティングオブジェクトまたは装置5020、5022、5024、5026、5028などは、PDA、オーディオ/ビデオ装置、移動電話、MP3プレーヤー、パーソナルコンピュータ、ラップトップなどの異なる装置を備えることができることが理解される。
それぞれのオブジェクト5010、5012など、およびコンピューティングオブジェクトまたは装置5020、5022、5024、5026、5028などは、1つまたは複数の他のオブジェクト5010、5012など、および1つまたは複数の他のコンピューティングオブジェクトまたは装置5020、5022、5024、5026、5028などと、通信ネットワーク5040を介して、直接にまたは間接的に通信することができる。図50では単一の要素として示されてはいるが、ネットワーク5040は、図50のシステムにサービスを提供する他のコンピューティングオブジェクトおよびコンピューティング装置を含むことができ、かつ/または図示されていない相互接続された複数のネットワークを表すことができる。それぞれのオブジェクト5010、5012など、または5020、5022、5024、5026、5028などはさらに、本明細書の開示のさまざまな実施形態に従って提供された列ベースエンコードおよびクエリ処理と通信し、それらに対して処理を実施し、またはそれらを実現するのに適した、APIを利用することがあるアプリケーション5030、5032、5034、5036、5038などのアプリケーション、または他のオブジェクト、ソフトウェア、ファームウェアおよび/ないしハードウェアを含むことができる。
分散コンピューティング環境をサポートするさまざまなシステム、コンポーネントおよびネットワーク構成が存在する。例えば、有線もしくは無線システムによって、ローカルネットワークによって、または広範囲に分散したネットワークによって、コンピューティングシステムを一体に接続することができる。現在、多くのネットワークが、広範囲に分散したコンピューティングに対するインフラストラクチャを提供し、多くの異なるネットワークを包含するインターネットに結合されているが、さまざまな実施形態で説明した列ベースエンコードおよびクエリ処理に付随して実施される例示的な通信に対しては、任意のネットワークインフラストラクチャを使用することができる。
したがって、クライアント/サーバ、ピアツーピア、ハイブリッドアーキテクチャなど、ネットワークトポロジおよびネットワークインフラストラクチャのホストを利用することができる。「クライアント」は、それが関係していない別のクラスまたはグループのサービスを使用するあるクラスまたはグループのメンバである。クライアントは、別のプログラムまたはプロセスによって提供されるサービスを要求するプロセス、すなわち概ね一組の命令またはタスクであることができる。このクライアントプロセスは、これらの別のプログラムまたはサービスに関する機能上の詳細を一切「知る」必要なしに、要求したサービスを利用する。
クライアント/サーバアーキテクチャ、特にネットワークシステムにおいて、クライアントは通常、別のコンピュータ、例えばサーバによって提供される共用ネットワーク資源にアクセスするコンピュータである。図50の例では、非限定的な例として、コンピュータ5020、5022、5024、5026、5028などは、クライアントと考えることができ、コンピュータ5010、5012、などはサーバと考えることができ、サーバ5010、5012などは、クライアントコンピュータ5020、5022、5024、5026、5028などからデータを受け取り、データを保存し、データを処理し、クライアントコンピュータ5020、5022、5024、5026、5028などにデータを送信するなどのデータサービスを提供するが、状況に応じて、どのコンピュータも、クライアントまたはサーバ、またはその両方とみなすことができる。これらのコンピューティング装置はいずれも、本明細書において1つまたは複数の実施形態に関して説明した列ベースエンコードおよびクエリ処理を巻き込むことがある、データを処理し、データをエンコードし、データを問い合わせ、またはサービスもしくはタスクを要求する操作を実施することができる。
サーバは一般に、インターネット、無線ネットワークインフラストラクチャなどのリモートまたはローカルネットワークを介してアクセス可能なリモートコンピュータシステムである。第1のコンピュータシステムでクライアントプロセスがアクティブであり、第2のコンピュータシステムでサーバプロセスがアクティブであることがあり、これらは互いに通信媒体を介して通信し、したがって分散機能を提供し、複数のクライアントが、サーバの情報収集能力を利用することを可能にする。列ベースエンコードおよびクエリ処理に従って利用される、独立型の、または複数のコンピューティング装置もしくはオブジェクトを横切って分散した任意のソフトウェアオブジェクトを提供することができる。
通信ネットワーク/バス5040が例えばインターネットであるネットワーク環境では、サーバ5010、5012などをウェブサーバとすることができ、クライアント5020、5022、5024、5026、5028などは、それらのウェブサーバを利用して、ハイパーテキストトランスファプロトコル(HTTP)などの知られているいくつかのプロトコルのうちの任意のプロトコルを介して通信する。分散コンピューティング環境の特徴として、サーバ5010、5012などが、クライアント5020、5022、5024、5026、5028などの働きをすることもある。
(例示的なコンピューティング装置)
前述のとおり、有利には、本明細書に記載した技法を、大量のデータを迅速に問い合わせることが望ましい任意の装置に適用することができる。したがって、あらゆる種類のハンドヘルド、ポータブルおよび他のコンピューティング装置およびコンピューティングオブジェクトを、さまざまな実施形態とともに使用すること、すなわち、ある装置が、莫大な量のデータをスキャンし、または処理して、迅速かつ効率的に結果を得たいあらゆる場合に、さまざまな実施形態とともに使用することが企図される。したがって、図51で後述する以下の汎用リモートコンピュータは、コンピューティング装置の唯一の例ではない。
必須ではないが、装置またはオブジェクトに対するサービスの開発者が使用するために、オペレーティングシステムを介して実施形態を部分的に実現することができ、かつ/または本明細書に記載されたさまざまな実施形態の1つないし複数の機能的態様を実行するように動作するアプリケーションソフトウェアに、実施形態を含めることができる。ソフトウェアは、クライアントワークステーション、サーバまたは他の装置などの1つまたは複数のコンピュータによって実行されるプログラムモジュールなどのコンピュータ実行可能命令の一般的な文脈で記述することができる。コンピュータシステムは、データを伝達するために使用することができるさまざまな構成およびプロトコルを有し、したがって、特定の構成またはプロトコルを、限定するためのものとみなすべきではないことを当業者は理解するであろう。
したがって、図51は、本明細書に記載された実施形態の1つまたは複数の態様を実現することができる適当なコンピューティングシステム環境5100の一例を示すが、上述のことから明らかなように、コンピューティングシステム環境5100は、適当なコンピューティング環境の一例にすぎず、コンピューティングシステム環境5100が、使用または機能の範囲に関して何らかの限定を提示することは意図されていない。さらに、コンピューティング環境5100が、例示的な動作環境5100中に示されたコンポーネントのうちの任意の1つのコンポーネントまたはコンポーネントの組合せに関係した何らかの依存関係または要件を有すると解釈すべきではない。
図51に関して、1つまたは複数の実施形態を実現する例示的なリモート装置は、コンピュータ5110の形態の汎用コンピューティング装置を含む。限定はされないが、コンピュータ5110のコンポーネントには、処理ユニット5120、システムメモリ5130、およびシステムメモリを含むさまざまなシステムコンポーネントを処理ユニット5120に結合するシステムバス5122が含まれる。
コンピュータ5110は一般に、さまざまなコンピュータ可読媒体を含み、コンピュータ5110がアクセスすることができる使用可能な任意の媒体であることができる。システムメモリ5130は、リードオンリーメモリ(ROM)および/またはランダムアクセスメモリ(RAM)など、揮発性および/または不揮発性メモリの形態のコンピュータ記憶媒体を含むことができる。一例として、メモリ5130はさらに、限定はされないが、オペレーティングシステム、アプリケーションプログラム、他のプログラムモジュールおよびプログラムデータを含むことができる。
ユーザは、入力装置5140を介してコンピュータ5110にコマンドおよび情報を入力することができる。さらに、出力インタフェース5150などのインタフェースを介して、システムバス5122に、モニタまたは他のタイプの表示装置が接続される。モニタに加えて、コンピュータはさらに、出力インタフェース5150を介して接続することができるスピーカ、プリンタなどの他の周辺出力装置を含むことができる。
コンピュータ5110は、リモートコンピュータ5170などの1つまたは複数の他のリモートコンピュータへの論理結合を使用して、ネットワーク環境または分散環境で動作することができる。リモートコンピュータ5170は、パーソナルコンピュータ、サーバ、ルータ、ネットワークPC、ピア装置もしくは他の一般的なネットワークノード、または他の任意のリモート媒体消費もしくは伝送装置とすることができ、コンピュータ5110に関して上で説明した要素のうちの任意の要素または全ての要素を含むことができる。図51に示した論理接続は、ローカルエリアネットワーク(LAN)、ワイドエリアネットワーク(WAN)などのネットワーク5172を含むが、他のネットワーク/バスを含むこともできる。このようなネットワーク環境は、家庭、オフィス、企業規模のコンピュータネットワーク、イントラネットおよびインターネットにおいて珍しいものではない。
前述のとおり、さまざまなコンピューティング装置およびネットワークアーキテクチャに関する例示的な実施形態を説明したが、その根底をなす概念は、大規模データを圧縮し、または大規模データに関するクエリを処理することが望ましい任意のネットワークシステムおよび任意のコンピューティング装置またはコンピューティングシステムに適用することができる。
また、アプリケーションおよびサービスが効率的なエンコードおよびクエリ技法を使用することを可能にする同じ機能または類似の機能、例えば適当なAPI、ツールキット、ドライバコード、オペレーティングシステム、制御、独立型のまたはダウンロード可能なソフトウェアオブジェクトなどを実現する方法は複数ある。したがって、本明細書の実施形態は、API(または他のソフトウェアオブジェクト)の見地から、ならびに列ベースエンコードおよび/またはクエリ処理を提供するソフトウェアまたはハードウェアオブジェクトから企図される。したがって、本明細書に記載されたさまざまな実施形態は、全体がハードウェアとして実現される態様、一部がハードウェア、一部がソフトウェアとして実現される態様、ならびに全体がソフトウェアとして実現される態様を有することができる。
本明細書では、語「例示的な」が、例、実例または例示を意味するために使用される。疑いを回避するため、本明細書に開示された主題はこのような例によって限定されない。さらに、本明細書において「例示的」と記述された態様または設計は、他の態様または設計よりも好ましいまたは有利であるとは必ずしも解釈されず、当業者に知られている例示的な等価の構造および技法を排除することを意味するものでもない。さらに、「発明を実施するための形態」または「特許請求の範囲」において用語「含む(includes)」、「有する(has)」、「含む(contains)」および他の類似の語が使用される限りにおいて、疑いを回避するため、このような用語は、開いた遷移語(open transition word)としての用語「含む(comprising)」と同様に、包括的(inclusive)であり、追加の要素または他の要素を排除しないことが意図される。
前述のとおり、本明細書に記載したさまざまな技法は、ハードウェアもしくはソフトウェアとともに、または、適当な場合には、ハードウェアとソフトウェアの両方とともに実現することができる。本明細書で使用するとき、用語「コンポーネント」、「システム」なども同様に、ハードウェア、ハードウェアとソフトウェアの組合せ、ソフトウェア、または実行中のソフトウェアであるコンピュータに関係したエンティティ(entity)を指すことが意図されている。例えば、コンポーネントは、限定はされないが、プロセッサ上で実行中のプロセス、プロセッサ、オブジェクト、エグゼキュータブル(executable)、実行のスレッド、プログラム、および/またはコンピュータであることができる。例示として、コンピュータ上で実行中のアプリケーションとそのコンピュータはともに、コンポーネントでありえる。プロセスおよび/または実行のスレッド内に、1つまたは複数のコンポーネントが存在することができ、コンポーネントは、1つのコンピュータ上に局限され、かつ/または2つ以上のコンピュータ間に分散することができる。
前述のシステムは、いくつかのコンポーネント間の対話に関して説明した。このようなシステムおよびコンポーネントは、それらのコンポーネントまたは指定されたサブコンポーネント、指定されたコンポーネントもしくはサブコンポーネントの一部、および/または追加のコンポーネント、ならびに上記のもののさまざまな置換および結合を含むことができることが理解できる。サブコンポーネントは、(階層的に)親コンポーネント内に含まれるのではなく、他のコンポーネントに通信可能に結合されたコンポーネントとして実現することもできる。さらに、1つもしくは複数のコンポーネントを結合して、集計機能を提供する単一のコンポーネントとし、または1つもしくは複数のコンポーネントを分割して、別個のいくつかのサブコンポーネントにすることができること、および統合化された機能を提供するために、管理層などの任意の1つまたは複数の中間層を、このようなサブコンポーネントに通信可能に結合するように提供することができることに留意すべきである。本明細書に記載されたコンポーネントはさらに、本明細書に具体的には記載されてはいないが、一般に当業者には知られている1つまたは複数の他のコンポーネントと対話することができる。
記載した主題に従って実現することができる方法は、以前に説明した例示的なシステムを考慮し、さまざまな図の流れ図を参照することによって、よりいっそう理解される。説明を単純にするため、これら方法を一連のブロックとして示し、説明したが、あるブロックは、本明細書に示され、記載された順序とは異なる順序で実行することができ、かつ/または他のブロックと同時に実行することができるため、請求の主題は、ブロックの順序によって限定されないことを理解すべきである。流れ図によって、一連でないフロー、すなわち枝分かれしたフローを示したが、同じ結果または類似の結果を達成する別のさまざまな枝、フロー経路およびブロックの順序を実現することができることが理解される。さらに、以下に記載する方法を実現するのに、示した全てのブロックが必要であるというわけでない。
本明細書に記載したさまざまな実施形態に加えて、他の類似の実施形態を使用することができること、または、記載した実施形態(1つもしくは複数)から逸脱することなく、それらの実施形態と同じ機能もしくは等価の機能を実行するために、対応する実施形態(1つもしくは複数)に変更および追加を実施されることができることを理解されたい。また、複数の処理チップまたは複数の装置が、本明細書に記載した1つまたは複数の機能の実行を分担することができ、同様に、ストレージは、複数の装置を横切って達成することができる。したがって、本発明は、単一の実施形態だけに限定されるものではなく、添付された特許請求の範囲に基づく幅、趣旨および範囲の中で解釈されるべきである。