IP Force 特許公報掲載プロジェクト 2022.1.31 β版

知財求人 - 知財ポータルサイト「IP Force」

▶ タブロー ソフトウェア,インコーポレイテッドの特許一覧

特表2022-507977複雑なデータベースクエリにおけるクエリフラグメントの重複の除去
(19)【発行国】日本国特許庁(JP)
(12)【公報種別】公表特許公報(A)
(11)【公表番号】
(43)【公表日】2022-01-18
(54)【発明の名称】複雑なデータベースクエリにおけるクエリフラグメントの重複の除去
(51)【国際特許分類】
   G06F 16/2453 20190101AFI20220111BHJP
   G06F 16/28 20190101ALI20220111BHJP
【FI】
G06F16/2453
G06F16/28
【審査請求】有
【予備審査請求】未請求
(21)【出願番号】P 2021529388
(86)(22)【出願日】2019-11-07
(85)【翻訳文提出日】2021-07-20
(86)【国際出願番号】 US2019060226
(87)【国際公開番号】W WO2020131243
(87)【国際公開日】2020-06-25
(31)【優先権主張番号】16/231,302
(32)【優先日】2018-12-21
(33)【優先権主張国・地域又は機関】US
(81)【指定国・地域】
(71)【出願人】
【識別番号】508311813
【氏名又は名称】タブロー ソフトウェア,インコーポレイテッド
(74)【代理人】
【識別番号】100079108
【弁理士】
【氏名又は名称】稲葉 良幸
(74)【代理人】
【識別番号】100109346
【弁理士】
【氏名又は名称】大貫 敏史
(74)【代理人】
【識別番号】100117189
【弁理士】
【氏名又は名称】江口 昭彦
(74)【代理人】
【識別番号】100134120
【弁理士】
【氏名又は名称】内藤 和彦
(72)【発明者】
【氏名】フォーゲルゲサン,エイドリアン
(72)【発明者】
【氏名】ハウベンスチャイルド,マイケル
(72)【発明者】
【氏名】コール,リック
(72)【発明者】
【氏名】フィニス,ジャン
(72)【発明者】
【氏名】ゼン,マニュエル
(72)【発明者】
【氏名】ミュールバウアー,トビアス
(72)【発明者】
【氏名】ノイマン,トーマス
【テーマコード(参考)】
5B175
【Fターム(参考)】
5B175EA03
5B175KA12
(57)【要約】
データベースエンジンは、クライアントからデータベースクエリを受信する。データベースエンジンは、データベースクエリを解析して、複数のクエリ演算子を含むクエリ演算子ツリーを構築する。データベースエンジンは、重複排除最適化パスを含む1つまたは複数の最適化パスをクエリ演算子ツリー上で実施して、最適化された実行プランを作成する。重複排除最適化パスは:クエリ演算子ツリーの第1のトラバーサルを介してクエリ演算子のリストを作成することと、第2のクエリ演算子に等価の第1のクエリ演算子を、ハッシュマップに基づいて、クエリ演算子ツリーの第2のトラバーサルを介して決定することと、クエリ演算子ツリーの第3のトラバーサルを介して、第2のクエリ演算子を第1のクエリ演算子にリンクするツリーノードに置き換えることと、を含む。データベースエンジンは、最適化された実行プランを実行してデータベースから結果セットを取り出し、この結果セットを返す。
【選択図】図1
【特許請求の範囲】
【請求項1】
1つまたは複数のコンピューティングデバイスを備えるデータベースエンジンであって、
各コンピューティングデバイスは、1つまたは複数のプロセッサ、およびメモリを有し、前記メモリは、前記1つまたは複数のプロセッサによって実行されるよう構成されている1つまたは複数のプログラムを格納し、前記1つまたは複数のプログラムは、
クライアントからデータベースクエリを受信することと、
前記データベースクエリを解析して、複数のクエリ演算子を含むクエリ演算子ツリーを構築することと、
重複排除最適化パスを含む1つまたは複数の最適化パスを、前記クエリ演算子ツリー上で実施して、最適化された実行プランを形成することであって、前記重複排除最適化パスは、
クエリ演算子のリストを、前記クエリ演算子ツリーの第1のトラバーサルを介して作成すること、
第2のクエリ演算子と等価である第1のクエリ演算子を、ハッシュマップに基づいて、前記クエリ演算子ツリーの第2のトラバーサルを介して決定すること、および
前記クエリ演算子ツリーの第3のトラバーサルを介して、前記第2のクエリ演算子を前記第1のクエリ演算子にリンクするツリーノードに置き換えることを含む、最適化された実行プランを形成することと、
前記最適化された実行プランを実行して、前記データベースから結果セットを取り出すことと、
前記結果セットを前記クライアントに返すことと、を行うための命令を含む、データベースエンジン。
【請求項2】
前記クエリ演算子のリスト内の前記クエリ演算子間の依存関係のリストを計算することをさらに含み、前記第2のトラバーサルは、依存関係を有さないクエリ演算子が依存関係のあるクエリ演算子の前に訪問されるよう、前記依存関係のリストに基づいて、前記クエリ演算子ツリーの幅優先、後行順のトラバーサルを含む、請求項1に記載のデータベースエンジン。
【請求項3】
第3のクエリ演算子が前記クエリ演算子ツリー内に等価のクエリ演算子を有さない、という決定に従って、前記依存関係のリストを更新して、前記第3のクエリ演算子が依存関係を有することを指定し、前記第3のクエリ演算子の前記親が、前記幅優先、後行順のトラバーサル中に選択されないようにすることをさらに含む、請求項2に記載のデータベースエンジン。
【請求項4】
前記第1のクエリ演算子をマテリアライズできる場合にのみ、前記第2のクエリ演算子を前記ツリーノードに置き換えることをさらに含む、請求項1に記載のデータベースエンジン。
【請求項5】
前記第1のクエリ演算子は、GROUPBy演算子、GROUPJOIN演算子、SORT演算子、WINDOW演算子またはTEMP演算子のうちの1つである、請求項4に記載のデータベースエンジン。
【請求項6】
前記第1のクエリ演算子にリンクする前記ツリーノードは、前記第2のクエリ演算子に対応する前記最適化された実行プランの一部の実行インスタンス数を減らす、請求項1に記載のデータベースエンジン。
【請求項7】
前記第1のトラバーサルおよび前記第3のトラバーサルは、前記クエリ演算子ツリーの深さ優先、先行順のトラバーサルを含む、請求項1に記載のデータベースエンジン。
【請求項8】
前記重複排除最適化パスの前にツリーリファクタリング最適化パスを実施して、前記クエリ演算子ツリー内の重複クエリ演算子を増やすために前記クエリ演算子ツリーをリファクタリングすることをさらに含む、請求項1に記載のデータベースエンジン。
【請求項9】
前記重複排除最適化パスを禁止する前記重複排除最適化パスに先行する、1つまたは複数の最適化パスをオフにすることをさらに含む、請求項1に記載のデータベースエンジン。
【請求項10】
前記第1のクエリ演算子が前記第2のクエリ演算子と等価であるかどうかを決定することは、
前記第1のクエリ演算子および前記第2のクエリ演算子の入力演算子が等価であるかどうかを決定することと、
前記第1のクエリ演算子と前記第2のクエリ演算子が等価のプロパティを有するかどうかを決定することとを含む、請求項1に記載のデータベースエンジン。
【請求項11】
前記第1のクエリ演算子と前記第2のクエリ演算子が等価のプロパティを有するかどうかを決定することは、前記第1のクエリ演算子および前記第2のクエリ演算子の前記入力演算子の情報ユニットマッピングを使用する、請求項10に記載のデータベースエンジン。
【請求項12】
前記第1のクエリ演算子が前記第2のクエリ演算子と等価であるかどうかを決定することは、可換性および結合性の規則を使用する、請求項10に記載のデータベースエンジン。
【請求項13】
前記ハッシュマップは、前記クエリ演算子ツリーの前記第2のトラバーサルの間に新しいクエリ演算子が訪問されたときに更新される、請求項1に記載のデータベースエンジン。
【請求項14】
前記第1のクエリ演算子が前記第2のクエリ演算子と等価であるかどうかを決定することは、前記第1のクエリ演算子および前記第2のクエリ演算子に対応する前記サブツリー内の、1つまたは複数の一致しないクエリ演算子を無視する、請求項1に記載のデータベースエンジン。
【請求項15】
前記第1のクエリ演算子および前記第2のクエリ演算子を包含する、第4のクエリ演算子を作成することと、
前記クエリ演算子ツリーの前記第3のトラバーサルを介して、前記第1のクエリ演算子および前記第2のクエリ演算子を、前記第4のクエリ演算子に置き換えることとをさらに含む、請求項1に記載のデータベースエンジン。
【請求項16】
前記第1のクエリ演算子および前記第2のクエリ演算子を包含する、第5のクエリ演算子を作成することと、
前記第5のクエリ演算子の結果を入力として使用する、第6のクエリ演算子を作成することと、
前記クエリ演算子ツリーの前記第3のトラバーサルを介して、前記第1のクエリ演算子を前記第5のクエリ演算子に置き換えること、および前記第2のクエリ演算子を前記第6のクエリ演算子に置き換えることとをさらに含む、請求項1に記載のデータベースエンジン。
【請求項17】
前記第1のクエリ演算子および前記第2のクエリ演算子が、親結合クエリ演算子の入力演算子であるという決定に従って、前記クエリ演算子ツリー内の前記親結合クエリ演算子を削除することと、前記親結合クエリ演算子を前記第1のクエリ演算子に置き換えることと、前記クエリ演算子ツリーから前記第2のクエリ演算子を消去することとをさらに含む、請求項1に記載のデータベースエンジン。
【請求項18】
前記第1のクエリ演算子および前記第2のクエリ演算子は、クエリバッチ内の異なるクエリに属し、前記クエリ演算子ツリーは、前記クエリバッチ内の異なるクエリを組み合わせる1つまたは複数のクエリ演算子を含む、請求項1に記載のデータベースエンジン。
【請求項19】
1つまたは複数のプロセッサおよびメモリを備えるコンピュータシステムによって実行されるよう構成された1つまたは複数のプログラムを格納する、非一時的コンピュータ可読記憶媒体であって、前記1つまたは複数のプログラムは、
クライアントからデータベースクエリを受信することと、
前記データベースクエリを解析して、複数のクエリ演算子を含む前記クエリ演算子ツリーを構築することと、
重複排除最適化パスを含む1つまたは複数の最適化パスを、前記クエリ演算子ツリー上で実施して、最適化された実行プランを形成することであって、前記重複排除最適化パスは、
クエリ演算子のリストを、前記クエリ演算子ツリーの第1のトラバーサルを介して作成すること、
第2のクエリ演算子と等価である第1のクエリ演算子を、ハッシュマップに基づいて、前記クエリ演算子ツリーの第2のトラバーサルを介して決定すること、および
前記クエリ演算子ツリーの第3のトラバーサルを介して、前記第2のクエリ演算子を前記第1のクエリ演算子にリンクするツリーノードに置き換えることを含む、最適化された実行プランを形成することと、
前記最適化された実行プランを実行して、前記データベースから結果セットを取り出すことと、
前記結果セットを前記クライアントに返すことと、を行うための命令を含む、非一時的コンピュータ可読記憶媒体。
【請求項20】
データベースからデータを取り出す方法であって、
1つまたは複数のコンピューティングデバイスを有し、各コンピューティングデバイスが、1つまたは複数のプロセッサと、前記1つまたは複数のプロセッサによって実行されるよう構成された1つまたは複数のプログラムを格納するメモリとを有するコンピュータシステムにおいて、
クライアントからデータベースクエリを受信することと、
前記データベースクエリを解析して、複数のクエリ演算子を含むクエリ演算子ツリーを構築することと、
重複排除最適化パスを含む1つまたは複数の最適化パスを、前記クエリ演算子ツリー上で実施して、最適化された実行プランを形成することであって、前記重複排除最適化パスは、
クエリ演算子のリストを、前記クエリ演算子ツリーの第1のトラバーサルを介して作成すること、
第2のクエリ演算子と等価である第1のクエリ演算子を、ハッシュマップに基づいて、前記クエリ演算子ツリーの第2のトラバーサルを介して決定すること、および
前記クエリ演算子ツリーの第3のトラバーサルを介して、前記第2のクエリ演算子を前記第1のクエリ演算子にリンクするツリーノードに置き換えることを含む、最適化された実行プランを形成することと、
前記最適化された実行プランを実行して、前記データベースから結果セットを取り出すことと、
前記結果セットを前記クライアントに返すこととを含む、方法。
【発明の詳細な説明】
【技術分野】
【0001】
本開示の実装形態は、一般的にリレーショナルデータベースシステムに関し、より具体的には、クエリ実行の性能を改善するシステム機能に関する。
【背景技術】
【0002】
データベースエンジンはクエリを受信し、1つまたは複数のデータベーステーブルからデータを取り出し、このクエリによって要求されたデータを提供する。データベースクエリは、特有のクエリ言語、例えばSQLで表現される。一般的に、データベースクエリは、所望のデータを指定する際に、データの取り出し方法についての詳細な実行プランを指定しない。例えば、SQLでは、クエリには、所望のデータ列を指定するSELECT句、所望の列を含むテーブルを指定するFROM句、およびデータの選択方法の条件を指定するWHERE句が含まれる。SQLクエリには、GROUP By句、HAVING句、および/またはORDER BY句を含めることもできる。各クエリを解析し、実行プランを構築し、このプランを実行して要求された結果を取り出すかどうかは、データベースエンジンに依存する。これにより、データベースエンジンに大きな柔軟性がもたらされることとなる。一方で、同じクエリに対して異なる実行プランがあると、結果を取り出すための実行時間が大幅に異なる可能性がある。例えば、1つの実行プランでは1秒未満で結果を取り出せるのに対し、もう1つのプランではまったく同じ結果を取り出すのに数分かかる、といったことが起こり得る。この問題に対処するため、データベースエンジンは典型的に、実行性能を向上させるための1つまたは複数の最適化レイヤーを含む。あいにく、既存のデータベースエンジンでは、特定の種類の複雑なクエリを最適化することが困難である。
【発明の概要】
【0003】
SQLクエリがデータベースエンジンによって受信されると、クエリが解析され、抽象構文ツリーに変換される。セマンティック分析は、構文ツリーを演算子ツリーに変換する。演算子ツリーを構築すると、構文ツリーとスキーマ情報が組み合わされ、テーブル名と列名が解決され、クエリ内の内部参照が解決される。論理最適化中に、データベースエンジンは定数畳み込み、述語プッシュダウン、結合の並べ替え、およびその他の最適化技術を適用する。本明細書に記述するデータベースエンジンは、重複するサブクエリを削除できるため、冗長なクエリ動作の実行を回避できる。
【0004】
複雑なデータベースクエリ内の重複するクエリフラグメントを除去することにより、リアルタイムのデータ探索を強化する方法が提供される。いくつかの実装形態に従って、この方法は、それぞれが1つまたは複数のプロセッサおよびメモリを有する1つまたは複数のコンピューティングデバイスを有するデータベースエンジンで実施される。メモリは、1つまたは複数のプロセッサによる実行用に構成された1つまたは複数のプログラムを格納する。1つまたは複数のプログラムが実行されて、データベース(例えばSQLデータベース)からデータを取り出す。データベースエンジンは、クライアントからデータベースクエリを受信する。データベースエンジンは、データベースクエリを解析して、複数のクエリ演算子を含むクエリ演算子ツリーを構築する。データベースエンジンは、最適化された実行プランを作成するために、重複排除最適化パスを含む1つまたは複数の最適化パスを、クエリ演算子ツリー上で実施する。重複排除最適化パスは、(i)クエリ演算子ツリーの第1のトラバーサルを介してクエリ演算子のリストを作成することと、(ii)第1のクエリ演算子が第2のクエリ演算子と等価であることを、ハッシュマップに基づいて、クエリ演算子ツリーの第2のトラバーサルを介して決定することと、(iii)クエリ演算子ツリーの第3のトラバーサルを介して、第2のクエリ演算子を第1のクエリ演算子にリンクするツリーノードに置き換えることと、を含む。データベースエンジンは、最適化された実行プランを実行してデータベースから結果セットを取り出し、結果セットをクライアントに返す。
【0005】
いくつかの実装形態では、データベースエンジンは、クエリ演算子のリスト内のクエリ演算子間の依存関係のリストを計算する。第2のトラバーサルは、依存関係を有さないクエリ演算子が依存関係のあるクエリ演算子の前に訪問されるよう、依存関係のリストに基づくクエリ演算子ツリーの幅優先、先行順のトラバーサルである。いくつかの実装形態では、第3のクエリ演算子が等価のクエリ演算子を有さない場合、依存関係のリストが更新され、第3のクエリ演算子に依存関係があることを指定し、第3のクエリ演算子の親が、幅優先、後行順のトラバーサル中に選択されないようにする。
【0006】
いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子をマテリアライズできる場合にのみ、第2のクエリ演算子をツリーノードに置き換える。例えば、データベースエンジンは、以前に計算された結果を保存したり取り出したりするよりも再計算(または再マテリアライズ)の方が優れている可能性のある、ヒューリスティックを採用する。これは、関連するクエリ演算子(例えば結合演算子)が大きな結果を生成するため、この大きな結果を保存したり取り出したりすることによってメモリおよび/または帯域幅に関する性能の問題が発生する可能性があるからである。いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子がGROUPBy演算子、GROUPJOIN演算子、SORT演算子、WINDOW演算子またはTEMP演算子のいずれかである場合、第2のクエリ演算子を置き換える。
【0007】
いくつかの実装形態では、データベースエンジンが第1のクエリ演算子にリンクするために使用するツリーノードは、第2のクエリ演算子に対応する最適化された実行プランの一部の実行インスタンスの数を減らす。
【0008】
いくつかの実装形態では、クエリ演算子の第1のトラバーサルと第3のトラバーサルは、深さ優先、先行順のトラバーサルである。
【0009】
いくつかの実装形態では、データベースエンジンは、重複排除最適化パスの前にツリーリファクタリング最適化パスを実施して、クエリ演算子ツリーをリファクタリングする。これにより、クエリ演算子ツリー内の重複するクエリ演算子の数が増加する。言い換えると、リファクタリングにより、重複排除最適化パスが、重複するかまたは冗長であるクエリ演算子を削除する機会が増えることとなる。いくつかの実装形態では、データベースエンジンは、重複排除最適化パスに先行し、重複排除最適化パス(例えば、クエリ演算子ツリー内の重複クエリ演算子の数を減らし得るパス、機会を少なくし得るパス、あるいは重複を見つけることを困難にし得るパス)を禁止する可能性のある、1つまたは複数の最適化パスをオフにするか、抑制するか、あるいは実行しない。
【0010】
いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子が第2のクエリ演算子と等価であるかどうかを、第1のクエリ演算子と第2のクエリ演算子の入力演算子が等価であるかどうかの決定、および/または第1のクエリ演算子と第2のクエリ演算子が等価のプロパティ(例えば、演算子が、選択述語、結合条件、またはスキャンされたテーブルである)を有するかどうかの決定、に基づいて決定する。いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子と第2のクエリ演算子の入力演算子の情報単位マッピング(IUMappingと呼ばれることもある)に基づいて、第1のクエリ演算子と第2のクエリ演算子が等価のプロパティを有していると決定する。いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子が第2のクエリ演算子と等価であるかどうかを決定する際に、クエリ演算子の可換性、結合性、および同様の代数的プロパティを考慮する。その間、データベースエンジンは、第1のクエリ演算子の代数表現と第2のクエリ演算子の代数表現との間のわずかな違いは無視する。いくつかの実装形態では、第1のクエリ演算子が第2のクエリ演算子と等価であるかどうかを決定する間、データベースエンジンは、第1のクエリ演算子および第2のクエリ演算子に対応するサブツリー内の、1つまたは複数の一致しないクエリ演算子(「透過」演算子と呼ばれることもある)を無視する。
【0011】
いくつかの実装形態では、ハッシュマップはクエリ演算子の署名によってインデックス付けされる。いくつかの実装形態では、ハッシュマップは、クエリ演算子ツリーの第2のトラバーサル中にクエリ演算子が訪問されると、更新される。
【0012】
いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子と第2のクエリ演算子を包含する第4のクエリ演算子を作成すること、および/またはクエリ演算子ツリーの第3のトラバーサルを介して、第1のクエリ演算子と第2のクエリ演算子を第4のクエリ演算子と置き換えることによって、クエリフラグメントをマージする。
【0013】
いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子と第2のクエリ演算子を包含する第5のクエリ演算子を作成すること、第5のクエリ演算子の結果を入力として使用する、第6のクエリ演算子を作成すること、および/またはクエリ演算子ツリーの第3のトラバーサルを介して、第1のクエリ演算子を第5のクエリ演算子に置き換え、かつ第2のクエリ演算子を第6のクエリ演算子に置き換えること、によって、クエリ演算子ツリーの集計階層を最適化する。
【0014】
いくつかの実装形態では、データベースエンジンは冗長な結合を削除する。例えば、第1のクエリ演算子および第2のクエリ演算子は親結合クエリ演算子の入力演算子であるという決定に従って、データベースエンジンは、クエリ演算子ツリー内の親結合クエリ演算子を削除し、それを第1のクエリ演算子に置き換え、クエリ演算子ツリーから第2のクエリ演算子を消去する。
【0015】
いくつかの実装形態では、データベースエンジンは、キャッシュメカニズムを使用して第1のクエリ演算子を実行した第1の結果をキャッシュすることにより、実行の中間結果をリサイクルおよび/またはキャッシュする。例えば、データベースエンジンは、キャッシュヒット率を最大化するLRUまたは同様のスキームを使用する。いくつかの実装形態では、データベースエンジンは永続キャッシュ(パックされたワークブックなど)を使用し、これにより将来のロードまたは最初のインプレッションが高速になる。
【0016】
いくつかの実装形態では、データベースエンジンは、バッチクエリ間で重複するクエリ動作を削除する。第1のクエリ演算子と第2のクエリ演算子はクエリバッチ内の異なるクエリに属し、クエリ演算子ツリーには、クエリバッチ内の異なるクエリを組み合わせた1つまたは複数のクエリ演算子(例えば、UNIONALL演算子)が含まれる。
【0017】
いくつかの実装形態に従って、データベースエンジンは、1つまたは複数のプロセッサ、メモリ、およびメモリに格納された1つまたは複数のプログラムを含む。プログラムは、1つまたは複数のプロセッサによって実行されるように構成される。プログラムは、本明細書に記載の方法のいずれかを実施するための命令を含む。
【0018】
いくつかの実装形態に従って、非一時的コンピュータ可読記憶媒体は、1つまたは複数のプロセッサおよびメモリを有するコンピュータシステムによる実行のために構成されている1つまたは複数のプログラムを格納する。1つまたは複数のプログラムは、本明細書に記載の方法のいずれかを実施するための命令を含む。
【0019】
これにより、複雑なデータベースクエリにおけるクエリフラグメントの重複を削除または除去することによって、より効率的な処理を提供する方法、システム、およびコンピュータ可読媒体が開示される。
【0020】
前述の一般的な説明および以下の詳細な説明は、ともに例示的かつ説明的であり、特許請求される本発明のさらなる説明を提供することを意図している。
【図面の簡単な説明】
【0021】
効果的なデータベースクエリ処理を提供する前述のシステムおよび方法をよりよく理解するため、以下の図面と併せて、以下の実施形態の説明を参照されたい。図面中、同じ参照符号は図全体を通して同様の部分を指す。
【0022】
図1】いくつかの実装形態に従う、データベースシステムのためのコンテキストを示す図である。
図2】いくつかの実装形態に従う、コンピューティングデバイスのブロック図である。
図3A-3B】いくつかの実装形態に従う、コンピュータシステムで実装されるクエリ実行システムのブロック図である。
図3C】いくつかの実装形態に従う、クエリ重複排除最適化パスで使用されるIUMappingの概念を組み込んだクエリツリーの例を示す。
図4A-4L】いくつかの実施形態に従う、クエリ演算子ツリー、およびそれらが重複フラグメントの除去によってどのように最適化されるかを示す。
図5A-5I】いくつかの実施形態に従う、クエリ演算子ツリーの構築処理、クエリ演算子ツリーの最適化処理、およびクエリ演算子ツリーの実行処理のフローチャートを提示する。
図6】いくつかの実施形態に従う、ハッシュベースの重複排除プロセスの擬似コードを提示する。
【0023】
ここで、実装形態を参照すると、その例は、添付の図面に示されている。以下の説明では、本発明の徹底した理解を提供するために、数多くの特定の詳細が記載される。しかしながら、本発明がこれらの特定の詳細を必要とせずに実施され得ることは当業者には明らかであろう。
【0024】
実装形態の説明
図1に、いくつかの実装形態が動作するコンテキストを示す。ユーザ100は、デスクトップコンピュータ、ラップトップコンピュータ、タブレットコンピュータ、またはモバイルコンピューティングデバイスなどのパーソナルデバイス102と相互作用する。パーソナルデバイス102は、コンピューティングデバイス200の一例である。「コンピューティングデバイス」という用語にはサーバコンピュータも含まれる。サーバコンピュータは、1人のユーザが使用する個人用デバイスよりもはるかに強力であり、一般的には、ユーザによって間接的にのみアクセスされる。例示的なコンピューティングデバイス200は、図2に関して以下に説明され、デバイス200上で実行される様々なソフトウェアプログラムまたはモジュールを含む。いくつかの実装形態では、パーソナルデバイス102は、1つまたは複数のデスクトップデータソース224(例えばCSVファイルまたはスプレッドシートファイル)を含む。いくつかの実装形態では、パーソナルデバイス102は、データベースエンジン120を含み、データベースエンジン120は、1つまたは複数のリレーショナルデータベース122(例えばSQLデータベース)へのアクセスを提供する。いくつかの実装形態では、パーソナルデバイスは、ユーザ100がデスクトップデータソース224および/またはリレーショナルデータベース122からデータ視覚化を作成するために使用するデータ視覚化アプリケーション222を含む。このようにして、いくつかの実装形態によって、ユーザは、パーソナルデバイス102にローカルに格納されているデータを視覚化することが可能となる。
【0025】
いくつかの事例では、パーソナルデバイス102は、1つまたは複数の通信ネットワーク108を介して、1つまたは複数の外部データベースサーバ106および/またはデータ視覚化サーバ104に接続する。通信ネットワーク108は、ローカルエリアネットワークおよび/またはインターネットなどの広域ネットワークを含んでもよい。いくつかの実装形態では、データ視覚化サーバ104は、パーソナルデバイス102上のウェブブラウザ220内で実行されるデータ視覚化ウェブアプリケーションを提供する。いくつかの実装形態では、データ視覚化機能は、ローカルアプリケーション222と、データ視覚化サーバ104によって提供される特定の機能との、両方によって提供される。例えば、データ視覚化サーバ104は、リソースを大量に消費する動作に使用されてもよい。いくつかの実装形態では、1つまたは複数のデータベースサーバ106は、データベースサーバ106に格納されている1つまたは複数のデータベース122へのアクセスを提供するデータベースエンジン120を含む。図1に示されるように、データベースエンジン120および対応するデータベース122は、ローカルパーソナルデバイス102上またはデータベースサーバ106上のいずれかに存在してもよい。いくつかの実装形態(ここには示されていない)では、データ視覚化サーバ104は、データベースエンジン120および1つまたは複数のデータベース122を含む。
【0026】
図2は、いくつかの実装形態に従う、コンピューティングデバイス200を示すブロック図である。本明細書で使用される場合、「コンピューティングデバイス」という用語は、パーソナルデバイス102と、データベースサーバ106またはデータ視覚化サーバ104などのサーバの、両方を含む。コンピューティングデバイス200は、通常、メモリ214に格納されたモジュール、プログラム、および/または命令を実行し、それによって処理動作を実行するための1つまたは複数の処理ユニット/コア(CPU)202と、1つまたは複数のネットワークまたは他の通信インターフェース204と、メモリ214と、これらの構成要素を相互接続するための1つまたは複数の通信バス212と、を含む。通信バス212は、システムコンポーネント間の通信を相互接続および制御する回路網を含んでもよい。コンピューティングデバイス200は、ディスプレイデバイス208、1つまたは複数の入力デバイスまたは機構210を備える、ユーザインターフェース206を含んでもよい。いくつかの実装形態では、入力デバイス/入力機構120はキーボードを含む。いくつかの実装形態では、入力デバイス/機構は、ディスプレイデバイス208に必要に応じて表示される「ソフト」キーボードを含み、ユーザがディスプレイ208に表示される「キーを押す」ことを可能にする。いくつかの実装形態では、ディスプレイ208および入力デバイス/機構210は、タッチスクリーンディスプレイ(タッチセンシティブディスプレイとも称される)を含む。いくつかの実装形態では、メモリ214は、DRAM、SRAM、DDR RAM、または他のランダムアクセス固体メモリデバイスなどの高速ランダムアクセスメモリを含む。いくつかの実装形態では、メモリ214は、1つまたは複数の磁気ディスク記憶デバイス、光ディスク記憶デバイス、フラッシュメモリデバイス、または他の不揮発性固体記憶デバイスなどの不揮発性メモリを含む。いくつかの実装形態では、メモリ214は、CPU(複数可)202から遠隔に位置する1つまたは複数の記憶デバイスを含む。メモリ214、または代替的にメモリ214内の不揮発性メモリデバイス(複数可)は、非一時的コンピュータ可読記憶媒体を含む。いくつかの実装形態では、メモリ214、またはメモリ214のコンピュータ可読記憶媒体は、以下のプログラム、モジュール、およびデータ構造、またはそれらのサブセットを格納する。
・様々な基本的なシステムサービスを処理し、ハードウェアに依存するタスクを実施するための手順を含むオペレーティングシステム216;
・通信モジュール218。コンピューティングデバイス200を他のコンピュータおよびデバイスに接続するために使用され、これは1つまたは複数の通信ネットワークインターフェース204(有線または無線)および1つまたは複数の通信ネットワーク、例えばインターネット、他の広域ネットワーク、ローカルエリアネットワーク、メトロポリタンエリアネットワークなどのような通信ネットワークを介して行われる。
・ウェブブラウザ220(または他のクライアントアプリケーション)。これにより、ユーザ100はネットワークを介して遠隔のコンピュータまたはデバイスと通信することが可能となる。いくつかの実装形態では、ウェブブラウザ220は、データ視覚化サーバ104からダウンロードされたデータ視覚化ウェブアプリケーション(図示せず)を実行する。いくつかの実装形態では、データ視覚化ウェブアプリケーション(図示せず)は、データ視覚化アプリケーション222をローカルに格納する代替の方法である。
・データ視覚化アプリケーション222。これにより、ユーザは様々なデータソースからデータ視覚化を作成することが可能となる。データ視覚化アプリケーション222は、デスクトップデータソース224(例えばCSVファイルまたはフラットファイル)、ローカルに格納されたリレーショナルデータベース122、または別のデバイス(データベースサーバ106など)に格納されたデスクトップデータソースまたはリレーショナルデータベース122、などの1つまたは複数のデータソースからデータを取り出す。次に、データ視覚化アプリケーションは、取り出した情報を生成して1つまたは複数のデータ視覚化によって表示する。
・1つまたは複数のデスクトップデータソース224。データ視覚化アプリケーション222によって使用可能および表示可能なデータを有する。データソース224は、スプレッドシート、XMLファイル、フラットファイル、CSVファイル、テキストファイル、JSONファイル、またはデスクトップデータベースファイルなど、多くの異なる方法でフォーマットすることができる。典型的に、デスクトップデータソース224は、他のアプリケーション(例えば、スプレッドシートアプリケーション)によっても使用される。
・データベースエンジン120。データベースクエリ226(例えば、データ視覚化アプリケーションからのクエリ)を受信し、対応するデータを返す。データベースエンジン120は、典型的には複数の実行可能モジュールを含む。
・データベースエンジン120。クエリパーサ240を呼び出し、このクエリパーサ240は受信した各クエリ226(例えば、SQLデータベースクエリ)を解析して、クエリオペレーターツリー228を形成する。演算子ツリーは、代数ツリーと呼ばれることもある。いくつかの実装形態では、クエリパーサ240は、クエリコンパイラ242内に含まれている。
・データベースエンジン120は、各クエリ演算子ツリー228を実行可能コード230に変換するクエリコンパイラ242を含む。簡略化のため、クエリコンパイラ242は、コンパイラとも呼ばれる。いくつかの実装形態では、コンパイラ242は、効率的な実行プランを生成するためにクエリ演算子ツリー228を変更するオプティマイザ244を含む。オプティマイザは一般的には、クエリ演算子ツリーの構造と要求されたデータに基づいて、複数のタイプの最適化を識別することができる。例えば、いくつかの実装形態では、条件式の外部で、条件付き部分式などの部分式をいつ巻き上げるかを識別する。実行可能コードが実行されると、値が計算され巻き上げされた式として保存され、保存された値は、後に部分式が検出された場合に使用される。このようにして、部分式は行ごとに1回計算され、計算されたこの値は、同じ部分式が再度検出されたときに再利用される。いくつかの事例では、計算された値は、CPU202(複数可)のレジスタに格納される。いくつかの実装形態では、コンパイラ242および/またはオプティマイザ242は、データ構造、例えばハッシュマップおよびクエリ演算子228間の依存関係のリストなどをメモリ214に格納して、最適化パスをサポートまたはガイドする。
・データベースエンジン120は、クエリコンパイラ242によって生成されたコード230(本明細書ではクエリ実行プランと呼ばれることもある)を実行するクエリ実行モジュール250を含む。
・データベースエンジン120は、各プロセスによるメモリ使用率を追跡し、必要に応じて動的にメモリを割り当てる、クエリメモリマネージャ252も含む。いくつかの実装形態では、メモリマネージャ252は、コンパイルされたコードの実行中にメモリが不足している場合はそれを検出する。いくつかの実装形態では、クエリメモリマネージャ252は、クエリ実行モジュール250と通信する。
【0027】
上述の識別された実行可能モジュール、アプリケーション、または手順のセットの各々は、1つまたは複数のメモリデバイスに格納され得、かつ上述の機能を実行するための命令のセットに対応する。上述の識別されたモジュールまたはプログラム(すなわち、命令のセット)は、単独のソフトウェアプログラム、手順、またはモジュールとして実装される必要はなく、したがって、これらのモジュールの様々なサブセットは、様々な実装形態において組み合わされるか、または別様に再配置され得る。いくつかの実装形態では、メモリ214は、上述の識別されたモジュールおよびデータ構造のサブセットを格納する。いくつかの実装形態では、メモリ214は、上述されていない追加のモジュールまたはデータ構造を格納し得る。
【0028】
図2は、コンピューティングデバイス200を示しているが、図2は、本明細書で説明されている実装形態の構造的概略としてではなく、存在し得る様々な特徴の機能的説明としてより意図されている。実際には、当業者によって認識されるように、別々に示されたアイテムを組み合わせることができ、いくつかのアイテムを分離することができる。
【0029】
標準のリレーショナルデータベースクエリエンジンは、論理的に最適化されたプランを評価するために、関係代数ツリー(例えば、演算子ツリー228)に依存する。典型的な代数ツリー228は、その葉が基本関係に対応し、ツリー228内の各ノードがそのサブツリーのノードのみに基づいて評価され得るという優れた特性を有する。ツリー内のノードを評価するため、典型的な「イテレータエンジン」は、ノードの子に対応するサブツリーから中間結果を取り出すことによって機能する。
【0030】
一部のデータベースエンジンは、論理最適化の一部としてアクセスパスを選択する。結合された列にインデックスが存在すると、インデックスのネステッドループ結合を使用することが可能となり、これにより異なる結合順序の最適性に影響を与える可能性がある。このため、アクセスパスは典型的に、結合の並べ替えの一部として選択される。次に、データベースエンジンは、演算子ツリー内の代数演算子ごとに物理的な実装を選択する。いくつかの実装形態では、このフェーズ中に、データベースエンジンは適切なアクセスパスとインデックスを選択して、要求されたデータを可能な限り高速に取り出す。いくつかの実装形態によれば、最適化された演算子ツリーはネイティブマシンコードにコンパイルされる。次に、このコンパイル済みコードがロードされ、実行時にデータベースエンジンにリンクされ、そして実行される。したがって、いくつかの実装形態では、データベースエンジンは、基本的にデータベースクエリの最適化JITコンパイラとして機能する。
【0031】
いくつかの実装形態では、効率的なコード生成を可能にするため、実装では生成/消費実行モデルを使用する。この実行モデルでは、すべての演算子のコードが融合され、これにより、システムは演算子ツリー全体を介して次のパイプラインブレーカーまで、一度に1つのタプルをプッシュすることが可能となる。
【0032】
いくつかの実装形態では、データベースエンジンは「Morsel駆動の並列処理」を使用する。この並列化モデルでは、ワークはワーカースレッド間で動的に分散される。タプルは、数千のタプルのチャンクである、いわゆるmorselの形でワーカースレッドに渡される。ワーカースレッドは、morselを取得し処理するときに、スレッドの局所性を考慮に入れる。
【0033】
いくつかの実装形態では、データベースエンジンのオプティマイザとクエリエンジンは、データベースストレージレイヤーから分離されている。これにより、データベースエンジンは異なるストレージ形式の大規模なセットで機能することが可能となる。
【0034】
図3Aおよび3Bは、いくつかの実装形態に従う、コンピュータシステム200によって実装されたクエリ実行システムのブロック図である。実行システム300は、データベースクエリ226(例えばSQLクエリ)を受信するクエリパーサ240を含む。クエリパーサ240は、各データベースクエリ226を解析して、クエリ演算子ツリー228を形成する。いくつかの実装形態によれば、オプティマイザ244は、1つまたは複数の最適化パス308(例えば、パス308-1、308-D、および308-N)を実施して、クエリ演算子ツリー228を最適化し、最適化されたクエリ演算子ツリーを生成する。いくつかの実装形態によれば、重複排除最適化パス308-Dは、入力として、1つまたは複数の初期最適化パス308-1によって出力された最適化されたクエリ演算子ツリーを受け取り、1つまたは複数の重複クエリ演算子を削除する。いくつかの実装形態では、重複排除最適化パス308-Dに続く1つまたは複数の最終最適化パス308-Nは、クエリ演算子ツリー出力をさらに最適化して、最適化された実行プラン230を生成する。図3Aでは、最適化パス308を含むボックスが最適化された実行プラン230を生成するように示されているが、いくつかの実装形態では、コンパイラ(例えば図2を参照して前述したクエリコンパイラ242)に最適化パス308が、オプティマイザ(例えばオプティマイザ244)の一部として含まれており、コンパイラは、最適化された実行プラン(本明細書では、クエリ実行プランまたはコードと呼ばれることもある)を生成する。図2を参照して前述したように、実行モジュール(例えばモジュール250)は、いくつかの実装形態によれば、コードまたは最適化された実行プラン230を実行して、クエリ結果314を生成する。
【0035】
いくつかの実装形態では、中間コンパイラは、最適化パス308によって出力されたクエリ演算子ツリーをコンパイルして中間表現を形成し、中間表現はその後、最適化された実行プラン230にコンパイルされる。このステップは典型的に、論理的な最適化も含む。いくつかの実装形態では、実行セレクタが中間コンパイラに連結されている。実行セレクタは、1つまたは複数のクエリ特性と1つまたは複数のデータベース特性を識別して、クエリの実行方法を決定する。いくつかの実装形態では、実行セレクタは、中間表現を処理するために複数の実行オプションのうちの1つを選択する。いくつかの実装形態では、複数の実行オプションは、コンパイルなしの直接解釈、コード最適化がまったくないかほとんどないコンパイル(例えば「安価な」最適化)、およびより重要なレベルのコード最適化によるコンパイルを含む。複数の実行オプションには、クエリのコンパイル時間とクエリの実行時間の間にトレードオフがある。
【0036】
いくつかの実装形態では、実行セレクタはヒューリスティック処理を実装して複数の実行オプションから実行プランを選択する。いくつかの実装形態では、ヒューリスティック処理により、クエリのコンパイル時間とクエリの実行時間の合計が最小化される。いくつかの実装形態では、クエリのコンパイル時間は中間表現のサイズに基づいて推定される。いくつかの実装形態では、クエリ実行時間は、データベースクエリ226に対応する結果セットを取り出すためにアクセスされるかまたはタッチされる、タプル(例えばデータベース122内の行)の数に基づいて、推定される。
【0037】
いくつかの実装形態では、データベースクエリ226は、複数のサブクエリにセグメント化され、各サブクエリは、実行ブロックに変換される。いくつかの実装形態では、セグメントは実行パイプラインに基づいている。いくつかの実装形態では、上記の実行セレクタは、複数のサブクエリのうちの1つに対応する各実行ブロックを個別に扱う。つまり、実行セレクタは、中間コンパイラから各実行ブロックを受け取り、それぞれの実行ブロックの1つまたは複数のクエリ特性を識別する。実行セレクタは、それぞれの実行ブロックのクエリ実行時間とクエリコンパイル時間を推定する。次に、推定クエリ実行時間と推定クエリコンパイル時間が分析され、それらが解釈基準、コンパイル基準、および最適化されたコンパイル基準のうちの1つまたは複数を満たしているかどうかを決定する。次に、実行セレクタは、複数の実行オプションのうちの1つを選択して、複数のサブクエリのうちの1つに対応するそれぞれの実行ブロックを処理する。いくつかの実装形態では、データベースクエリ226がセグメント化されていない場合であっても、中間表現は複数の実行ブロックに分割される。次に、実行セレクタは、前述したように各実行ブロックを個別に扱う。
【0038】
いくつかの実装形態では、実行セレクタは、実行オプションを決定するときに、類似性メトリックを使用して、新しいクエリを以前に実行されたクエリと比較する。いくつかの実装形態では、類似性メトリックは時間推定データを使用する。いくつかの実装形態では、類似性メトリックは、アクセスされたテーブルの特性、例えばテーブルの同一性、テーブルサイズまたはインデックスの存在を比較する。いくつかの実装形態では、類似性メトリックは、クエリ構造および/または複雑さを比較する。
【0039】
図3Bは、いくつかの実装形態に従う、クエリ重複排除最適化パス308-Dを示すブロック図である。クエリ重複排除最適化パス308-Dは、クエリ演算子リスト318(例えば、入力クエリ演算子ツリー228内のすべてのクエリ演算子のリスト)を生成するための、入力クエリ演算子ツリー228の深さ優先、先行順のツリートラバーサル316を含む。続いて、最適化パス308-Dは、クエリ演算子ツリー228を、幅優先、後行順322でトラバースし、これはハッシュマップ324(例えば、クエリ演算子シグネチャによって索引付けされる)および/または依存関係のリスト320によって導かれる。いくつかの実装形態では、依存関係リスト320および/またはハッシュマップ324は、ツリートラバーサル322の間に更新される。ツリートラバーサル322は、等価であるクエリ演算子326のリストを生成する。いくつかの実装形態によれば、重複排除最適化パス308-Dは、続いてクエリ演算子ツリー228を、深さ優先、先行順328でトラバースし、クエリ演算子ツリー228から1つまたは複数のツリー等価または重複クエリ演算子を削除して、最適化されたクエリ演算子ツリー330を生成する。
【0040】
用語の例、式の最適化
以下の説明の背景情報として、用語の例について簡単に説明する。「演算子」という用語は、JOIN、SORT、SELECT、MAP、KMEANSなどすべてのクエリ演算子(例えばSQL代数演算子)を指す。演算子は入力セットを操作し、出力セットを生成する。対照的に、「式」という用語はスカラー式を指す。式はいくつかのスカラー引数を用い、別のスカラー値を返し、「+」および「-」などの従来の式を含む。式には、CaseExpressionなどの特別なSQL式、およびCachingExpressionなどの実装固有の式も含まれる。さらに、式には、ゼロ引数を用いる式、例えばConstantおよび、CURRENT_USERなどの特殊関数も含まれる。
【0041】
以下の説明で使用されるその他の用語には、「集計」および「情報単位(IU)」が含まれる。集計は、タプルのセットを1つの値に集計するために(例えばGROUPByクエリおよびWindowクエリで)使用される。集計の例には、SUM、MIN、MAXおよびAVGが含まれる。本説明で使用する別の概念は、IU概念である。IUは、クエリ最適化の間またはコード生成時の間に、タプル内の特定のスカラー値を識別する。IUは、その識別子(例えばメモリアドレス)によって識別される。IUは、そのメンバ変数内にタイプ情報を格納する。いくつかの実装形態に従って、IUは、最適化の間またはコード生成時の間にのみ存在する。いくつかの実装形態では、代数ツリーを仮想マシンまたはアセンブリコードに変換すると、IU抽象化が削除され、個々のスカラー値は、クエリ実行の異なるポイントに存在するレジスタによって識別される。
【0042】
いくつかの実装形態では、共通部分式除去(CSE)を適用して式を最適化する。いくつかの実装形態では、CSEは、式ツリーの等価性を意識したハッシュを返すgetSignature関数を使用する。式ツリーが等価である場合、それらは同じ署名を有する。例えば、式ツリー「a+b」と「b+a」は同じ署名を返す。いくつかの実装形態では、getSignatureが非等価な式に対して同じハッシュ値を返す唯一のケースとして、ハッシュ衝突が発生する場合がある。CSEのいくつかの実装形態では、2つの式の等価性を確認する関数、isEquivalentも使用する。この関数が使用されるのは、getSignatureが、ハッシュ衝突が原因で非等価である式に対して同じ署名を返す可能性があるためである。
【0043】
重複排除アルゴリズムの設計
重複排除アルゴリズムに対する例示的な実装形態または設計の選択について本明細に説明する。いくつかの実装形態では、何らかのやり方でマテリアライズする演算子のみを重複排除し、時相演算子を導入しない。いくつかの実装形態では、サブツリーの結果を複数のアップストリームコンシューマにストリーミングせず、データのマテリアライズされた表現を複数回スキャンすることにより、クエリ演算子ツリーの結果を再利用する。このような場合、演算子(JOIN演算子など)の重複を排除するには、JOIN結果をマテリアライズするTEMP演算子を導入することによって、複数のEXPLICITSCAN演算子がJOIN結果を再利用できるようにする必要がある。このようなTEMP演算子の導入は、可能ではあるが、オーバーヘッドが発生する可能性がある。例えば、JOINが大きな結果セットを生成すると、完全な結果セットがマテリアライズされ、メモリに保持される。いくつかの事例では、JOIN結果を再計算するだけで、JOIN結果をマテリアライズして読み出すよりも安価となる(例えばメモリ帯域幅のため)。したがって、いくつかの実装形態では、TEMP演算子を導入せず、GROUPByおよびGROUPJOINなど、何らかの方法で完全な結果をマテリアライズする必要がある重複排除演算子のみを導入する。いくつかの実装形態では、GROUPBy演算子を重複排除すると、そのGROUPByの下位にある他のすべてのクエリ演算子(すなわちGROUPBy演算子の子演算子)も重複排除され、これにはJOINなどの非マテリアライズ演算子を含む。重複した非マテリアライズ演算子の上位にアップストリームマテリアライズ演算子がない場合、いくつかの実装形態では、非マテリアライズ演算子(実行例におけるJOIN演算子)が再実行される。いくつかの実装形態では、マテリアライズされた結果は再利用可能であるため、マテリアライズ演算子の結果はTEMP演算子にコピーする必要はなく、直接再利用される。
【0044】
いくつかの実装形態では、様々な要因(クエリ演算子の数など)を考慮して、所定の閾値によって定義された複雑なクエリにのみ重複排除最適化パスを適用する。いくつかの実装形態では、与えられたクエリにクエリの重複排除が適用されないかどうかをできるだけ早く検出し、検出された場合は早期に解決する。
【0045】
いくつかの実装形態では、重複排除の最適化は、いくつかのオプティマイザパスのうちの1つである。いくつかの実装形態では、重複排除最適化パスは、他のほとんどの最適化(例えば結合並べ替えパス)の後に実行される。
【0046】
いくつかの実装形態では、クエリフラグメントの重複排除(クエリ演算子の重複排除またはクエリの重複排除と呼ばれることもある)には、2つのクエリフラグメントが与えられた場合のクエリの包含(または等価性)を検出することと、クエリ演算子ツリーを効率的にトラバースすることと、包含されたすべてのクエリフラグメントを重複排除することとが含まれる。サブツリーを別のサブツリーの結果で置き換えることによって除去する前に、除去されたサブツリーと置換サブツリーが検証され、同等の結果が生成される。いくつかの実装形態では、2つの演算子ツリーの等価性を確立することは、代数レベルで構文上の等価性を証明することを含む。いくつかの実装形態では、(i)入力演算子が等価であり、(ii)演算子のプロパティ(選択述語、結合条件、スキャンされたテーブルなど)が等価である場合かつその場合にのみ、2つの演算子を等価であると見なす。
【0047】
リーフ演算子の場合、入力演算子がないため、上記の条件(i)は自明である。条件(ii)は、いずれかの式に非定数値が含まれているという理由だけで、偽と評価されるべきではない。いくつかの実装形態では、IUを介してすべての非定数値を参照し、各演算子は一意のIUの下で出力を生成する。これは、例えば、同じテーブルで結果テーブルスキャンを結合した後、異なる結合側からの列を明確にすることができるようにするためである。IUは一意であるため、いくつかの実装形態では、クエリフラグメント間の等価性を決定するために、等価であるIUを追跡する。いくつかの実装形態では、IUMappingを使用し、上記で指定した二重条件の修正形式を使用して、(i)入力演算子が等価であり、(ii)演算子のプロパティ(例えば選択述語、結合条件、スキャンされたテーブル)が等価である場合かつその場合にのみ、関係する入力演算子のIUMappingが与えられた場合、2つの演算子が等価であることを見つける。この等価性の定義は再帰的であるため、各演算子は、それ自体の出力IUを別の等価の演算子の出力IUにマッピングする、出力IUMappingを提供する。いくつかの実装形態では、各演算子は、その入力演算子のIUMappingを演算子依存の何らかの方法で組み合わせて、出力IUMappingを提供する。
【0048】
図3Cに、いくつかの実装形態による、クエリ重複排除最適化パスで使用されるIUMappingの概念を組み込んだクエリツリーの例を示す。矢印332、334、336、338、および340は、様々な演算子の出力間のIUMappingを示している。この例では、T2における3つのテーブルスキャン(演算子342、344、および346)は等価である。いくつかの実装形態では、3つのIUMappingのうち2つのみを明示的に格納し、推移性によって第3のマッピングを推測する。図3Cでは、T1におけるスキャンのマッピング(演算子350、354、および358)と、それぞれの親SELECT演算子(演算子352、356および360)は、簡素化のため非表示である。また、3つのJOIN出力350、352および354は等価である。ただし、第2のGROUPBy演算子352は、他の2つのGROUPBy演算子350および354とは異なる集計を計算する。したがって、トップレベルでは、第1のGROUPBy演算子360と第3のGROUPBy演算子362の間にIUMapping332のみが存在する。いくつかの実装形態では、3つのGROUPBy演算子360、362および364を、クエリフラグメントのマージを使用してMINとMAXの両方を同時に計算する、1つの共通のGROUPBy演算子に組み合わせる。
【0049】
いくつかの実装形態では、IUMappingは、IUをあるツリーフラグメントから別のツリーフラグメントにマッピングする。概念的には、これらは、IU(またはIUへのポインタ)を引数として用い何らかのユーティリティ関数を有する、順序付けられていないマップである。
【0050】
いくつかの実装形態では、関数(getSignature C++関数など)は、演算子サブツリーのセマンティック対応ハッシュを提供し、ハッシュベースの構造(順序付けられていないマップ)を使用して演算子ツリーにインデックスを付ける。いくつかの実装形態では、2つの演算子(例えばC++の例では「this」演算子と「other」演算子)の出力IU間の等価マッピングを確立する関数(例えばsignature establishEquivalenceMapping(Operator&other)を持つC++関数)を使用する。いくつかの実装形態では、演算子の特定のセマンティクスとその入力演算子に対するIUMappingに基づいて、等価性を確立する。いくつかの実装形態では、IUMappingが空であることとIUMappingが不在であることとを区別する。IUMappingの不在は、演算子ツリーの等価性を証明できなかったことを意味する。一方、IUMappingが空であることは、両方の演算子ツリーが同じ数のタプルを生成するが、それらのIUが互いにマップされないことを意味する。いくつかの実装形態では、等価マッピングの推移性も処理する。
【0051】
いくつかの実装形態では、署名の取得および/または等価性の確立に使用される関数(例えば、上記のgetSignature関数およびestablishEquivalenceMapping関数)は、代数表現間のわずかな違いを無視する。例えば、いくつかの実装形態では、以下のクエリフラグメント、
..(SELECT SUM(a)AS s1,MIN(b)AS m1 FROM t1)..
および
..(SELECT MIN(b)AS m2,SUM(a)AS s2 FROM t1)..
は、生成された列名が異なり、集計の順序が異なったとしても、マッピングs1→s2およびm1→m2と等価であると検出される。いくつかの実装形態では、この等価性を、代数レベルでGROUPBy演算子内の集計の元の順序が保持されていない場合に使用する。代わりに、このような場合には、代数ツリーでの集計の順序は内部の不安定なポインタに依存し、元のクエリが同じ順序で集計をリストした場合でも異なる場合がある。いくつかの実装形態では、他の演算子と同様の等価性の概念が使用される。いくつかの実装形態では、入力演算子が反転している場合でも、結合演算子の等価性が検出される。いくつかの実装形態では、生成された列の順序を考慮せずに、一連動作、UNION[ALL]、INTERSECT[ALL]、および/またはEXCEPT[ALL]の等価性を検出する。いくつかの実装形態では、(動作のための)個々の制限を考慮せずに、TABLESCAN動作の等価性を検出する。
【0052】
いくつかの実装形態では、getSignatureまたは同様の関数の速度を最適化する。例えば、いくつかの実装形態では、別の演算子との演算子等価性に影響を与え得る演算子の、すべての部分が含まれているわけではない。例えば、TableScanの署名には、残差と制限は含まれておらず、スキャンされたリレーションIDと述語の数のみが含まれる。場合によってはハッシュ衝突が発生するが、ハッシュ衝突はアルゴリズムの正確性に影響を与えない。これは、他の関数(例えばestablishEquivalenceMapping関数)が演算子を除外するためである。いくつかの実装形態では、ハッシュ衝突とハッシュ速度のトレードオフがある。いくつかの実装形態では、ほとんどの演算子ツリーに対し、クエリ重複排除の機会がないことは「安価な」ハッシュによってすでに十分に証明されている。したがって、署名の計算を安価に保つことにより、いくつかの実装形態では、ベイルアウト処理が、安価なハッシュがない場合よりもさらに急速に早期になされるようになる。
【0053】
いくつかの実装形態では、getSignature関数またはestablishEquivalenceMapping関数により、MapおよびSelectなどの演算子は、それに含まれる式が等価であるかどうかを確認する。いくつかの実装形態では、等価性を確認するために、CSEアルゴリズムで使用される関数(例えば、CSEを参照して前述したgetSignature関数およびisEquivalent関数)を使用する。いくつかの実装形態では、CSEで使用される機能を拡張して、等価性を確認するために拡張機能を再利用する前にIUMappingをサポートする。いくつかの実装形態では、等価性を確認する際に、演算子の可換性が考慮される。例えば、動作(IU1+IU2)-IU3は、マッピング{IU1→IU4,IU2→IU5,IU3→IU6}、またはマッピング{IU1→IU5,IU2→IU4,IU3→IU6}が与えられた場合は(IU4+IU5)-IU6と等価であるが、この2つは、マッピング{IU1→IU6,IU2→IU5,IU3→IU4}、または{IU1→IU5,IU2→IU6,IU3→IU4}を用いる場合は等価ではない。2番目のマッピングセットは、「+」演算子の可換性により、等価性につながる。
【0054】
重複排除アルゴリズムの例
いくつかの実装形態によれば、高レベルでは、重複排除アルゴリズムは3つのツリートラバーサルで構成される。まず、クエリ演算子ツリーの深さ優先、先行順トラバーサルは、クエリ演算子ツリー内の演算子(リストなど)と演算子間の依存関係(依存関係のリストなど)を収集する。次に、クエリ演算子ツリーの依存関係を意識した幅優先、後行順トラバーサルは、演算子の署名によってインデックス付けされたハッシュマップを利用することにより、等価のサブツリーを検出する。最後に、クエリ演算子ツリーの第3の深さ優先、先行順トラバーサルは、マテリアライズ演算子の上に参照ノード(EXPLICITSCANなど)を導入し、非マテリアライズ演算子をそのままにして、前のステップで検出された重複クエリフラグメントを削除する。
【0055】
第1のステップとして、いくつかの実装形態では、クエリ内で重複する可能性のあるサブツリーを列挙する。いくつかの実装形態では、サブツリーは特定の列挙順序で訪問される。すなわち、演算子は、その演算子のすべての入力演算子の等価性が確立された後にのみ訪問される。いくつかの実装形態によれば、重複が排除される可能性のある各演算子は、少なくとも1回訪問される。いくつかの実装形態では、重複が排除される可能性のある各演算子は、最大で1回訪問される。いくつかの実装形態では、不適格な演算子(例えば、重複排除最適化パスの候補ではない演算子)をできるだけ多くスキップする。いくつかの実装形態では、クエリ重複排除最適化パスの恩恵を受ける可能性が低いクエリ演算子ツリーをできるだけ早く検出し、検索と置換のプロセスを中止する。
【0056】
いくつかの実装形態では、幅優先、後行順トラバーサルでクエリ演算子ツリーを列挙する。後行順トラバーサルを使用することにより、いくつかの実装形態では、演算子のすべての入力が訪問された後にのみ、その演算子が訪問されることを確実にする。例えば、演算子の入力用のIUMappingは、その演算子自体に訪問する前に使用可能である。幅優先探索では、サブツリー全体の探索を早期に停止できる実装が可能なため、幅優先探索の方が深さ優先探索よりも優先される。幅優先探索によって演算子のすべての入力の等価マッピングが見つからなかった場合、この演算子自体に訪問しても意味がない。したがって、ほとんどのクエリでは、リーフノードの等価物を見つけることができない場合、アルゴリズムはリーフノードのみに訪問した後にすでに終了する場合がある。
【0057】
いくつかの実装形態では、幅優先トラバーサルは、各演算子の未解決の依存関係のセットを追跡することによって実装される。アルゴリズムは、未処理の演算子のリストから未処理の依存関係を有さない演算子を選択し、その演算子に訪問する。訪問が成功した場合(つまり、与えられた演算子と等価である別の演算子をアルゴリズムが検出した場合)、アルゴリズムは依存関係を実行済みとしてマークし、これにより現在の演算子に依存している演算子のブロックを解除する可能性がある。訪問が成功しなかった場合(つまり、他に等価の演算子がなかった場合)、アルゴリズムは依存関係をブロックしたままにする。これにより、どの親オペレーターも訪問されることはない。この方法では、アルゴリズムは、親演算子の入力演算子と等価のものを検出しなかったという理由で、親演算子と等価の演算子を検出しない可能性がある。
【0058】
いくつかの実装形態では、ツリーの最初のトラバーサルでは、演算子の追加の依存関係が考慮される。例えば、EARLYPROBEツリーノードは、対応するJOINノードまたは演算子の左側が訪問される前に訪問されることはない。いくつかの実装形態では、EARLYPROBEツリーノードとJOINの左側の間に人為的な依存関係を追加することにより、このトラバース順序を確実にする。
【0059】
いくつかの実装形態では、第1のツリートラバーサルの機能は、第2のツリートラバーサルに組み込まれるかその一部として実行される。同様に、いくつかの実装形態では、第2のツリートラバーサルと第3のツリートラバーサルとを1つのステップに組み合わせる。組み合わされたツリートラバーサルは、ツリー構造に応じて、冗長な重複クエリ演算子の一部またはすべてを識別して置き換えることがいまだ可能である。いくつかの実装形態では、ヒューリスティックアプローチを使用して、クエリ演算子のツリータイプ(パターンマッチング経由など)および/またはアプリケーションタイプの初期識別に基づいて、ツリートラバーサルのタイプを決定する。
【0060】
ハッシュベースの重複排除
以前に導入された、依存関係を意識した幅優先トラバーサルを使用してツリーをボトムアップでトラバースしている間、いくつかの実装形態では、訪問したすべての演算子を含むハッシュマップを保持する。このハッシュマップは、演算子の署名(Operator::getSignatureなど)によってインデックスが付けられる。このハッシュマップで現在の演算子を検索することにより、アルゴリズムは、等価である可能性のあるすべての演算子をすばやく取得できる。等価である可能性のあるすべての演算子の各々に対して、アルゴリズムは等価マッピングを確立できるかどうかを確認する。いくつかの実装形態によれば、そのようなマッピングが存在する場合、アルゴリズムは、その等価マッピングを記憶し、幅優先トラバーサルが対応する依存関係を実行済みとしてマークする。このプロセスの擬似コードの例を図6に示す。
【0061】
図6の擬似コードにおいて、演算子は、等価の演算子が存在する場合にのみブロック解除される。そうでない場合、演算子はブロックされたままになり、依存するすべての演算子が訪問されず、それによりトラバーサルが効果的にプルーニングされ、アルゴリズムが早期に中止される。
【0062】
重複したクエリフラグメントの置き換え
前のステップの後、アルゴリズムは等価の演算子のリストを収集している(例えば、図6の擬似コードの「equivalences」)。いくつかの実装形態では、続いて、クエリ演算子ツリーの深さ優先、先行順トラバーサルを実行する。いくつかの実装形態によれば、このトラバーサル中に、アルゴリズムは、EXPLICITSCAN演算子を導入することにより、このアルゴリズムが遭遇するすべての重複する演算子を重複排除する。いくつかの実装形態では、前のステップで確立された「equivalences」を使用することにより、現在訪問している演算子と等価の他の演算子を見つける。トップダウンで等価性を除去することにより、いくつかの実装形態では、サブツリー内にExplicitScan演算子が不必要に導入されないことを確実にする。ExplicitScan演算子は、ツリーのさらに上位で重複排除できるため、後で削除されることとなる。いくつかの実装形態では、結果全体を具体化する「マテリアライズ」演算子(GROUPBy、SORT、WINDOW、TEMPなど)を除去する。これらの演算子の結果は、追加のオーバーヘッドなしで複数回スキャンできる。一方、非マテリアライズ演算子の場合、一時的な結果を再利用目的で保持しておくためのTEMP演算子が導入される。これが性能にとって最適でない場合、いくつかの実装形態では、結果を再利用目的で一時的に保持しておくことを回避する。
【0063】
いくつかの実装形態では、EXPLICITSCANを導入するには、関係するIUの親を変更する必要がある。このステップは、IUMapping(例えば、前のフェーズでのOperator::establishIUMapping)を確立した、前のステップによって確立されたIUMappingを暗黙的に無効にする。この無効化は、いくつかの実装形態が重複したクエリフラグメントの検出と除去を2つの個別の段階に分割する別の理由である。
【0064】
いくつかの実装形態では、重複排除最適化パスを、結合並べ替えパス内に統合し、重複排除パスがスタンドアロンパスとして実装されている場合に可能な数よりも多くの共有サブツリーのインスタンスを検出する。
【0065】
いくつかの事例では、プッシュダウンの選択/初期プローブの導入によって、同一のクエリツリーが、もはや等価ではなくなるような方法で変更される。例えば、以下のクエリの場合、
SELECT s1.sum,s2.sum
FROM(SELECT SUM(a)AS s FROM t1 GROUP BY k)s1
JOIN(SELECT SUM(a)AS s FROM t1 GROUP BY k)s2 ON s1.k=s2.k
WHERE s1.k<>‘exclude’
s1.kの制限は、最初にs1にプッシュダウンされ、プッシュダウンされた制限により、s1とs2に対するツリーはもはや等価ではなくなり、これにより重複排除が防止される。同様に、EARLYPROBE演算子の導入は、クエリの重複排除を妨げる可能性がある。いくつかの実装形態では、推定に依存してEARLYPROBE動作が導入されるため、推定にとって無害に見える変更を加えると、クエリの重複排除が禁止される可能性がある。いくつかの実装形態では、性能のトレードオフを考慮して、各々のアップストリーム最適化を調整するか、これらの最適化をオフにするかのいずれかによって、前述のEARLYPROBEの問題および同様の禁止されたアップストリーム変形/最適化に対処する。
【0066】
ここで説明するアルゴリズムおよび実装形態は、様々なクエリ演算子タイプに対する重複排除をサポートする。含まれる演算子は、ASSERTSINGLE、EARLYPROBE、EXPLICITSCAN、EXTERNALFORMATSCAN(様々なフォーマット、TDEも含む)、GROUPBy、JOIN(すべての内部/外部/単一の変形を含む)、MAP、SELECT、すべての一連動作(UNION[ALL]、INTERSECT[ALL]、およびEXCEPT[ALL])、SORT(ORDER BY句のないLIMITも含む)、TABLECONSTRUCTION、TABLESCAN、TEMPおよびVIRTUALTABLEである。
【0067】
クエリグラフの例
図4A~4Lは、いくつかの実装形態に従う、本明細書において説明するクエリ重複排除最適化パスによって最適化されたクエリ演算子ツリー(クエリグラフと呼ばれることもある)のいくつかの例を示す。図4Bは、いくつかの実装形態に従う、図4Aに示されるクエリ演算子ツリー400の最適化されたバージョンである。図4Aでは、子クエリ演算子402-4(TABLESCAN演算子)を有するクエリ演算子402-2(GROUPBy演算子)が数回複製されているのが見られる(子演算子402-8を有する演算子402-6、子演算子402-12を有する演算子402-10、子演算子402-16を有する演算子402-14、および子演算子402-20を有する演算子402-18)。図4Bでは、クエリ演算子402-2は、クエリ演算子402-2を子演算子として有する新しいクエリ演算子404-2(EXPLICITSCAN演算子)に置き換えられている。他の重複クエリ演算子(演算子402-6、402-10、402-14および402-18)は、新しい「explicitscan」クエリ演算子404-4、404-6、404-8および404-10に置き換えられ、これらは、(線で示すように)第1の演算子402-2に戻って参照する。いくつかの実装形態では、相互参照を含む拡張クエリグラフ表現を使用して参照が実装される。この相互参照により、影響を受けるクエリのコンパイル時間と実行時間の両方が減少する。
【0068】
クエリ演算子ツリーは、図4Aに示すツリーなどのように、データ視覚化アプリケーション222の複雑なワークブックに共通して見られ、詳細レベル計算または上位Nフィルタを含むクエリの結果である。上記のように、高レベルでは、重複クエリ(クエリフラグメントと呼ばれることもある)の識別および置換または削除には、2つの異なる関係演算子ツリーの等価性の提供が含まれる。これは、いくつかの実装形態によれば、クエリの包含によって実装される処理である。いくつかの実装形態では、クエリの包含は、ダッシュボードのクエリバッチを最適化するマルチクエリ最適化、クエリ間にわたるクエリフラグメントのキャッシュ、マテリアライズドビューの存在下でのクエリ最適化、およびマテリアライズドビューに対する最適な更新プランの生成などの、他の最適化パスと共有される。
【0069】
図4Cは、いくつかの実装形態による、いくつかの重複クエリ動作を含むクエリ演算子ツリーの例を示す。クエリ演算子ツリーの右側にあるEXPLICITSCAN演算子からクエリ演算子ツリーの左側に向かって引かれた破線406-2、406-4、および406-6は、右側のサブツリーの大部分がクエリ演算子ツリーの左側のサブツリーの重複であること示している。図4Cに示すように、重複する動作を削除し、これらの動作を相互参照(EXPLICITSCAN演算子など)に置き換えると、コンパイル時間と同様クエリ実行時間が大幅に短縮される。図4Dは、重複するGROUPBy演算子がEXPLICITSCAN演算子ノードに置き換えられた別のクエリ演算子ツリーの例を示している。ノード408-4、408-6、408-8、および408-10(元はGROUPBy演算子)は、GROUPBy演算子408-2の結果を参照するEXPLICITSCAN演算子ノードである。同様に、ノード410-4、410-6、410-8、410-10、410-12、410-14、410-16、および410-18(元はGROUPBy演算子)は、GROUPBy演算子410-2の結果を参照するEXPLICITSCAN演算子ノードである。このツリーはさらに最適化でき得るが、線412-2、412-4、412-6、および412-8で示されるEARLYPROBE演算子は、各々のフラグメントでのクエリフラグメントの重複排除を禁止する。
【0070】
図4E~4Kは、いくつかの実装形態による、クエリフラグメントの重複排除のさらなる具体例を示している。図4Fは、図4Eに示されているクエリ演算子ツリーの最適化されたバージョンである演算子ツリーを示している。図4Eでは、子クエリ演算子(TABLESCAN演算子)を有するサブツリー412-2(GROUPBy演算子)が数回複製されているのが見られる(サブツリー412-4、412-6、412-8、および412-10)。図4Fでは、サブツリー412-4、412-6、412-8、および412-10が、サブツリー412-2を参照して、EXPLICITSCAN演算子ノード412-12、412-14、412-16、および412-18に置き換えられている。同様に、いくつかの実装形態に従って、図4H図4Gに示されているクエリ演算子ツリーの最適化されたバージョンを示し、図4J図4Iに示されているクエリ演算子ツリーの最適化されたバージョンを示している。
【0071】
図4Kは、いくつかの実装形態に従って、冗長結合を用いて最適化された演算子ツリーの例を示している(サブツリー間の線は、重複排除された演算子を示している)。図4Kでは、1つまたは複数のGROUPBY演算子がそれ自体と結合されており、結合条件によってこの結合がKey-Key-Joinに変化している。JOIN演算子の両側が同一であるため、いくつかの実装形態ではこの結合は完全に削除される。
【0072】
クエリフラグメントのマージ
いくつかの実装形態では、同一のサブクエリを重複排除するだけでなく、手元にある両方のサブクエリを包含し、両方のスキャンをこの組み合わされたクエリに置き換えるサブクエリを作成する。例えば、次のクエリ、
SELECT a,SUM(b),COUNT(b)FROM Extract GROUP BY a UNION ALL
SELECT a,SUM(b),AVG(b)FROM Extract GROUP BY a
において、2つのGROUPBy演算子は、以下のように1つのGROUPBy演算子に組み合わされる。
WITH combined AS(SELECT a,SUM(b),COUNT(b),AVG(b)FROM Extract GROUP BY a)
SELECT a,sum,count FROM combined UNION ALL
SELECT a,sum,avg FROM combined
【0073】
いくつかの実装形態では、複数のテーブルスキャンを使用して個別に計算するよりも、1回のテーブルスキャンで複数の集計を計算する方が安価であると認識される。GROUPBy演算子の集計リストをマージできることに加えて、いくつかの実装形態では、ツリー比較の目的のために、透過的な「transparent」演算子を使用する(つまり、これらの演算子が存在してもツリー比較が失敗する可能性はない。例えば、以下のクエリの場合:
SELECT a,SUM(calc)FROM (SELECT a,b+c AS calc FROM Extract) GROUP BY a UNION ALL
SELECT a,SUM(b),AVG(b)FROM Extract GROUP BY a
いくつかの実装形態によれば、クエリプランは図4Lに示す形式を有する。UNIONALL演算子442の左側のサブツリー444と右側のサブツリー446の形状がどのように異なるかに留意されたい。サブツリー444は、追加のMAP演算子を含む。この演算子は両方のツリーのマージを禁止すべきではない。この演算子は列を追加するだけで、他のすべての列を変更せずに通過するためである。同様に、次の演算子は同じプロパティを有する。
・WINDOW演算子:定義上、既存のすべての列を転送する間にのみ列を追加する。
・Key-Foreign Key-Join:KFK-Joinは列を追加するだけである。タプルを除外したり重複化することはない。特に、LOD計算(データ視覚化アプリケーション222によく見られる)に使用されるすべての結合はKFK結合である。いくつかの実装形態では、オプティマイザで外部キーを追跡し、KFK結合を検出する。
【0074】
さらに、いくつかの実装形態では、クエリフラグメントのマージおよび/またはクエリフラグメントの重複排除のための、追加の機会(例えば再帰動作またはネストされたGROUPBy演算子を扱うための)を発見するため、ツリートラバーサルを調整する。
集約階層
【0075】
いくつかの実装形態では、集約階層が導入される。例えば、いくつかの実装形態では、以下のクエリ、
SELECT a,b,SUM(c)FROM Extract GROUP BY a,b UNION ALL
SELECT a,NULL,SUM(c)FROM Extract GROUP BY a
を書き直す際に、次のように第1のGROUPByの結果を使用することにより、第2のGROUPByを計算する。
WITH agg1 AS (SELECT a,b,SUM(c)FROM Extract GROUP BY a,b)
SELECT a,b, sum FROM agg1 UNION ALL
SELECT a,NULL,SUM(sum)FROM agg1 GROUP BY a
【0076】
いくつかの実装形態では、すべてのGROUPByの入力にインデックスを付けるハッシュテーブルを使用し、続いて等価の入力の上に適用されるGROUPByをマージする。
【0077】
いくつかの実装形態では、集計関数には、それらを組み立て/分解する方法に関する情報が注釈として付けられている。例えば、オプティマイザは、SUMが他のSUMの上で計算できることを知っているが、AVGは最初にSUM/COUNTに分解する必要がある。
リサイクルと中間結果のキャッシュ
【0078】
いくつかの実装形態では、GROUPByハッシュテーブルおよびSORTヒープなどの中間結果をキャッシュし、クエリ間でそれらを再利用する。いくつかの実装形態では、このキャッシュを持続させる(例えば、パックされたワークブックに適応することによって将来のロードおよび最初のインプレッションが高速になるようにするために)。いくつかの実装形態では、HashTablesまたはSORT演算子にメモリを割り当てる方法と場所をクエリ状態から分離する。いくつかの実装形態では、LRUアルゴリズムなどのキャッシュ戦略を使用して、中間結果をキャッシュする。
【0079】
いくつかの実装形態では、結果をキャッシュするために一時テーブルを使用する。一時テーブル(フィルタテーブル、グループテーブルなど)がクエリの一部である場合、いくつかの実装形態では、異なるセッションにまたがる2つの一時テーブルが等価であることが証明される。いくつかの実装形態では、この等価性が証明されておらず、代わりに、crossDB一時データベースまたは非持続的共有テーブルなど、他の技術を使用してキャッシュヒット率を向上させる。
【0080】
クエリ間の最適化
いくつかの実装形態では、クエリバッチ内のクエリ間でサブクエリを重複排除する。構造上、クエリバッチには多くの重複が含まれる傾向がある。クエリの境界を越えてクエリフラグメントを重複排除および/またはマージすることにより、いくつかの実装形態では重複計算を回避する。いくつかの実装形態では、事前定義された動作(ExecutionTargetなど)を代数演算子に変換し、最上位の演算子(UNIONALL演算子など)を使用して個々のクエリを組み合わせる。いくつかの実装形態では、このクエリ間の最適化を可能にするようなやり方で、クエリバッチの送信および結果の受領を(例えばPostgres(登録商標)または類似のプロトコルを使用して)管理する。いくつかの実装形態では、すべてのクエリが使用可能なダッシュボードシナリオに対する、クエリ間の最適化を実施する。すべてのクエリが同時に使用可能であるため、いくつかの実装形態では、GROUPBy演算子をマージする(上記の「クエリフラグメントのマージ」のセクションを参照)。
【0081】
いくつかの実装形態では、マージされたか、さもなければ関連しないクエリ間でエラーが伝播することを回避する。例えば、マージされたクエリの1つによってのみ使用されるサブツリー内で例外が発生した場合、いくつかの実装形態では、正常に終了する可能性のある他のクエリの実行を続行する。一時テーブル(フィルタテーブル、グループテーブルなど)がクエリの一部である場合、いくつかの実装形態では、異なるセッションにまたがる2つの一時テーブルが等価であることが証明され、他の実装形態では、セッションにまたがる一時テーブルを含むクエリの組み合わせが回避される。
【0082】
マテリアライズドビューの更新
クエリ間の最適化と同様に、いくつかの実装形態では、マテリアライズドビューを更新するためにクエリを組み合わせる。例えば、次のシナリオにおいて、
CREATE MATERIALIZED VIEW viz1 AS(<query1>)WITH NO DATA
CREATE MATERIALIZED VIEW viz2 AS(<query2>)WITH NO DATA
CREATE MATERIALIZED VIEW viz3 AS(<query3>)WITH NO DATA
REFRESH MATERIALIZED VIEW viz1,viz2,viz3
いくつかの実装形態では、基礎となる3つのクエリすべてを一緒に最適化する。
【0083】
いくつかの実装形態(Tableauアプリケーションなど)では、各視覚化(「viz」と呼ばれることもある)ごとに1つのマテリアライズドビュー、またはダッシュボード内のフィルタを宣言することにより、この機能を使用する。すべてのビューが配置されるとすぐに、すべてのビューが一度に更新される。これにより、データベースサーバシステムは、ワークブックに必要なすべてのクエリを一度に最適化できる。いくつかの実装形態は、マテリアライズドビューに関する最適化のためのPostgres(登録商標)表現に依存している。いくつかの実装形態では、代数表現の挿入、消去、または同様の動作がマテリアライズドビューの最適化に使用される。いくつかの実装形態では、これらの機能を実装するために一時テーブル(「Temp Table」)を使用する。
【0084】
SQLおよびデータベースユーザ定義関数内での重複排除
ユーザ定義関数を使用することにより、1つの関数内で複数のステートメントが指定できるようになる。次の例を考察する。
CREATE FUNCTION updateMaterializedData()AS $$
TRUNCATE tab1;
TRUNCATE tab2;
INSERT INTO tab1(<query1>);
INSERT INTO tab2(<query2>);
$$ language sql;
【0085】
いくつかの実装形態では、個々のステートメントにクエリの重複排除を適用し、<query1>および<query2>からの共通のサブクエリを取り除く。いくつかの実装形態では、クエリがtab1またはtab2を参照している場合、確実に両方のクエリが正しい状態でテーブルを見るようにする。
【0086】
図5A~5Iは、いくつかの実装形態に従って、クエリ演算子ツリーを構築、最適化、および実行してデータベースからデータを取り出すための処理500のフローチャートを示す。処理500は、それぞれが1つまたは複数のプロセッサおよびメモリを有する1つまたは複数のコンピューティングデバイスを有するデータベースエンジンで実施される。メモリは、1つまたは複数のプロセッサによる実行用に構成された1つまたは複数のプログラムを格納する。1つまたは複数のプログラムが実行されて、データベース(例えばSQLデータベース)からデータを取り出す。
【0087】
データベースエンジン120は、クライアントからデータベースクエリ226を受信(502)する。データベースエンジン120(またはデータベースエンジン内のクエリパーサ240)は、データベースクエリ226を解析(504)して、複数のクエリ演算子を含むクエリ演算子ツリー228を構築する。データベースエンジンは、最適化された実行プラン230を形成するために、重複排除最適化パス308-Dの実施を含む1つまたは複数の最適化パス308を、クエリ演算子ツリー上で実施する(506)。
【0088】
いくつかの実装形態では、重複排除最適化パスは、クエリ演算子ツリー228の第1のトラバーサル316を介してクエリ演算子のリスト318を作成すること(520)と、第2のクエリ演算子と等価である第1のクエリ演算子を、ハッシュマップに基づいて、クエリ演算子ツリー228の第2のトラバーサル(例えばトラバーサル322)を介して決定すること(524)と、クエリ演算子ツリー228の第3のトラバーサル(例えばトラバーサル328)を介して、第2のクエリ演算子を第1のクエリ演算子にリンクするツリーノード(例えばEXPLICITSCAN演算子)に置き換える(532)こととを含む。データベースエンジンは、最適化された実行プランを実行して(514)データベースから結果セットを取り出し、結果セットをクライアントに返す(518)。
【0089】
図5Cを参照すると、いくつかの実装形態では、データベースエンジン120は、クエリ演算子のリスト318内のクエリ演算子間の依存関係のリスト320を計算する(536)。第2のトラバーサルは、依存関係のリスト320に基づくクエリ演算子ツリー228の幅優先、後行順トラバーサル(例えばトラバーサル322)を含み、これにより依存関係を有さないクエリ演算子は、依存関係を有するクエリ演算子の前に訪問される。いくつかの実装形態では、第3のクエリ演算子が等価のクエリ演算子を有さないとの決定に従って、データベースエンジン120は、依存関係のリスト320を更新して(538)、第3のクエリ演算子が依存関係を有することを示す。このようにして、第3のクエリ演算子の親は、幅優先、後行順トラバーサル中に選択されない。
【0090】
図5Eを参照すると、いくつかの実装形態では、データベースエンジン120は、第1のクエリ演算子がマテリアライズできる場合にのみ、第2のクエリ演算子をツリーノードに置き換える(548)。例えば、データベースエンジンは、以前に計算された結果を保存したり取り出したりするよりも再計算(または再マテリアライズ)の方が優れているヒューリスティックを採用する。これは、関連するクエリ演算子(例えば結合演算子)が大きな結果を生成するため、この大きな結果を保存したり取り出したりすることによってメモリおよび帯域幅に関する性能の問題が発生する場合があるからである。いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子がGROUPBy演算子、GROUPJOIN演算子、SORT演算子、WINDOW演算子、またはTEMP演算子のいずれかである場合、第2のクエリ演算子を置き換える(550)。
【0091】
図5Fを参照すると、いくつかの実装形態に従う、データベースエンジン120が第1のクエリ演算子にリンクするために使用するツリーノード(例えばEXPLICITSCAN演算子)は、第2のクエリ演算子に対応する最適化された実行プランの一部の実行インスタンスの数を減らす(552)。
【0092】
ここで図5Bに戻ると、いくつかの実装形態では、クエリ演算子の第1のトラバーサルおよび第3のトラバーサルは、クエリ演算子ツリーの深さ優先、先行順トラバーサルである(522、534)。
【0093】
ここで図5Aに戻ると、いくつかの実装形態では、データベースエンジン120は、重複排除最適化パスの前にツリーリファクタリング最適化パスを実行して(508)、クエリ演算子ツリーをリファクタリングすることによってクエリ演算子ツリー内の重複クエリ演算子の数を増やす。言い換えると、リファクタリングにより、重複排除最適化パスが、重複するかまたは冗長であるクエリ演算子を削除する機会が増えることとなる。いくつかの実装形態では、データベースエンジンは、重複排除最適化パスに先行し、重複排除最適化パスを禁止する(例えば、クエリ演算子内の重複クエリ演算子の数を減らす、機会を少なくする、または重複を見つけることを困難にする)1つもしくは複数の最適化パスをオフにするか、抑制するか、または実行しない(510)。
【0094】
ここで図5Dを参照すると、いくつかの実装形態では、データベースエンジン120は、第1のクエリ演算子が第2のクエリ演算子と等価であるかどうかを、第1のクエリ演算子および第2のクエリ演算子の各々の入力演算子が等価であるかどうかの決定(540)に基づいて、および/または第1のクエリ演算子と第2のクエリ演算子が等価のプロパティを有する(例えば演算子が選択述語、結合条件、またはスキャンされたテーブルである)かどうかの決定(544)に基づいて、決定する(524)。いくつかの実装形態では、データベースエンジン120は、第1のクエリ演算子と第2のクエリ演算子の入力演算子の情報単位マッピング(IUMappingと呼ばれることもある)に少なくとも基づいて、第1のクエリ演算子が第2のクエリ演算子と等価のプロパティを有していると決定する(546)。いくつかの実装形態では、データベースエンジンは、第1のクエリ演算子が第2のクエリ演算子と等価であるかどうかを決定するために、クエリ演算子の可換性、結合性、および同様の代数的特性を考慮する(542)。その間、データベースエンジンは、第1のクエリ演算子の代数表現と第2のクエリ演算子の代数表現との間のわずかな違いは無視する。
【0095】
ここで図5Bに戻ると、いくつかの実装形態では、第1のクエリ演算子が第2のクエリ演算子と等価であるかどうかを決定する間、データベースエンジンは、第1のクエリ演算子と第2のクエリ演算子に対応するサブツリー内の、1つまたは複数の一致しないクエリ演算子(「透過」演算子と呼ばれることもある)を無視する(528)。
【0096】
いくつかの実装形態では、ハッシュマップ324は、(例えば、署名計算関数の1つを使用して)クエリ演算子署名によってインデックス付けされる。いくつかの実装形態では、ハッシュマップは、クエリ演算子ツリーの第2のトラバーサル中にクエリ演算子が訪問されると、更新される(526)。
【0097】
次に図5Gを参照すると、いくつかの実装形態では、データベースエンジン120は、第1のクエリ演算子と第2のクエリ演算子を包含する第4のクエリ演算子を作成すること(554)、および/またはクエリ演算子ツリーの第3のトラバーサルを介して、第1のクエリ演算子と第2のクエリ演算子を第4のクエリ演算子と置き換えること(556)によって、クエリフラグメントをマージする。
【0098】
図5Hに示すように、いくつかの実装形態では、データベースエンジン120は、第1のクエリ演算子と第2のクエリ演算子を包含する第5のクエリ演算子を作成すること(558)、第5のクエリ演算子の結果を入力として使用する、第6のクエリ演算子を作成すること(560)、および/またはクエリ演算子ツリーの第3のトラバーサルを介して、第1のクエリ演算子を第5のクエリ演算子に置き換え、かつ第2のクエリ演算子を第6のクエリ演算子に置き換えること(562)、によって、クエリ演算子ツリーの集計階層を最適化する。
【0099】
いくつかの実装形態では、データベースエンジン120は、図5Iに示されるように、冗長な結合を削除する。例えば、第1のクエリ演算子と第2のクエリ演算子が親結合クエリ演算子の入力演算子であるという決定に従って、データベースエンジン120は、クエリ演算子ツリー内の親結合クエリ演算子を削除し(564)、それを第1のクエリ演算子に置き換え、クエリ演算子ツリーから第2のクエリ演算子を消去する。
【0100】
図5Aに戻ると、いくつかの実装形態では、データベースエンジン120は、キャッシュメカニズムを使用して第1のクエリ演算子を実行した第1の結果をキャッシュすることにより(516)、実行の中間結果をリサイクルおよび/またはキャッシュする。例えば、データベースエンジンは、キャッシュヒット率を最大化するLRUまたは同様のスキームを使用する。いくつかの実装形態では、データベースエンジンは永続キャッシュを使用するため(パックされたワークブックなど)、将来のロードまたは第一印象が高速になる。
【0101】
図5Bを参照すると、いくつかの実装形態では、データベースエンジン120は、バッチクエリ間で重複するクエリ動作を削除する(530)。第1のクエリ演算子と第2のクエリ演算子はクエリバッチ内の異なるクエリに属し、クエリ演算子ツリーには、クエリバッチ内の異なるクエリを組み合わせた1つまたは複数のクエリ演算子(例えば、UNIONALL演算子)が含まれる。
【0102】
本明細書で本発明の説明に使用される専門用語は、特定の実装形態を説明することのみを目的としており、本発明を限定することを意図するものではない。本発明の説明および添付の特許請求の範囲で使用される場合、単数形「a」、「an」、および「the」は、特に文脈が明示しない限り、複数形も含むことが意図される。本明細書で使用される「および/または」という用語は、1つまたは複数の関連するリストされたアイテムのありとあらゆる可能な組み合わせを指し、それらを包含することも理解されよう。本明細書で使用される場合、「含む」および/または「含んでいる」という用語は、述べられた特徴、ステップ、動作、要素、および/または構成要素の存在を指定するが、1つもしくは複数の他の特徴、ステップ、動作、要素、構成要素、および/またはそれらの群の存在または追加を排除しないことがさらに理解されよう。
【0103】
前述の記載は、説明の目的で、特定の実装形態を参照して記載されてきた。しかしながら、上記の例示的な論議は、網羅的であること、または本発明を開示された正確な形態に限定することを意図していない。上記の教示を考慮して、多くの修正および変形が可能である。実装形態は、本発明の原理およびその実際の応用を最もよく解説するために選択および記載され、それにより、当業者は、本発明および企図される特定の用途に好適な様々な修正を伴う様々な実装形態を最大限に利用することができる。
図1
図2
図3A
図3B
図3C
図4A
図4B
図4C
図4D
図4E
図4F
図4G
図4H
図4I
図4J
図4K
図4L
図5A
図5B
図5C
図5D
図5E
図5F
図5G
図5H
図5I
図6
【国際調査報告】