問合せ10: 索引の一部ではないフィールドによるデータのグループ化
乗客手荷物の出発地とすべての乗客の手荷物の数をフェッチし、出発地別にデータをグループ化します。
SELECT $flt_src as SOURCE, count(*) as COUNT FROM BaggageInfo $bag,
$bag.bagInfo.flightLegs[0].fltRouteSrc $flt_src GROUP BY $flt_src
計画:
{
"iterator kind" : "GROUP",
"input variable" : "$gb-2",
"input iterator" :
{
"iterator kind" : "RECEIVE",
"distribution kind" : "ALL_PARTITIONS",
"input iterator" :
{
"iterator kind" : "GROUP",
"input variable" : "$gb-1",
"input iterator" :
{
"iterator kind" : "SELECT",
"FROM" :
{
"iterator kind" : "TABLE",
"target table" : "BaggageInfo",
"row variable" : "$bag",
"index used" : "primary index",
"covering index" : false,
"index scans" : [
{
"equality conditions" : {},
"range conditions" : {}
}
]
},
"FROM variable" : "$bag",
"FROM" :
{
"iterator kind" : "FIELD_STEP",
"field name" : "fltRouteSrc",
"input iterator" :
{
"iterator kind" : "ARRAY_SLICE",
"low bound" : 0,
"high bound" : 0,
"input iterator" :
{
"iterator kind" : "FIELD_STEP",
"field name" : "flightLegs",
"input iterator" :
{
"iterator kind" : "FIELD_STEP",
"field name" : "bagInfo",
"input iterator" :
{
"iterator kind" : "VAR_REF",
"variable" : "$bag"
}
}
}
}
},
"FROM variable" : "$flt_src",
"SELECT expressions" : [
{
"field name" : "SOURCE",
"field expression" :
{
"iterator kind" : "VAR_REF",
"variable" : "$flt_src"
}
},
{
"field name" : "COUNT",
"field expression" :
{
"iterator kind" : "CONST",
"value" : 1
}
}
]
},
"grouping expressions" : [
{
"iterator kind" : "FIELD_STEP",
"field name" : "SOURCE",
"input iterator" :
{
"iterator kind" : "VAR_REF",
"variable" : "$gb-1"
}
}
],
"aggregate functions" : [
{
"iterator kind" : "FUNC_COUNT_STAR"
}
]
}
},
"grouping expressions" : [
{
"iterator kind" : "FIELD_STEP",
"field name" : "SOURCE",
"input iterator" :
{
"iterator kind" : "VAR_REF",
"variable" : "$gb-2"
}
}
],
"aggregate functions" : [
{
"iterator kind" : "FUNC_SUM",
"input iterator" :
{
"iterator kind" : "FIELD_STEP",
"field name" : "COUNT",
"input iterator" :
{
"iterator kind" : "VAR_REF",
"variable" : "$gb-2"
}
}
}
]
}
説明:
- この問合せでは、フライト出発地に基づいて旅客手荷物をグループ化し、1つのフライト出発地に属する手荷物の合計数を決定します。
- GROUP BYフィールド(この例では
bagInfo.flightLegs[0].fltRouteSrc
)はどの索引にも含まれていないため、グループ化を実行するには個別のGROUP演算子が必要です。このことは実行計画にGROUPイテレータが存在することによって示されています。2つのGROUPイテレータがあります。1つ(RECEIVEイテレータの上にある)はドライバで動作し、もう1つ(RECEIVEイテレータの下にある)はRNで動作します。 - 下位のGROUPイテレータの入力はSELECTイテレータです。このSELECTは、手荷物の
fltRouteSrc
およびcount
を返します。GROUPイテレータは、バッチ制限に達するまで動作します。バッチ制限が、生成される結果の最大数Nとして定義されている場合、最大N個のフライト出発地グループが作成されると、GROUPイテレータが停止します。バッチ制限が最大読取りバイト数として定義されている場合、この最大値に達すると停止します。GROUP演算子には入力変数があります。内側のGROUP演算子では、入力変数は$gb-1
で、外側のGROUP演算子では$gb-2
です。"iterator kind" : "GROUP","input variable" : "$gb-1",
- ここでは主キー索引が使用され、この例では、これはカバー索引ではありません(主索引のエントリに含まれないフィールドが問合せにあるため)。
- FROMイテレータがTABLEイテレータの場合、FROM変数は、使用されている索引がカバー索引かどうかに応じて、TABLEイテレータのindex row variableまたはrow variableのいずれかと同じになります。FROMイテレータに対するnext()コールがtrueを返すたびに、そのイテレータによって生成された結果に変数がバインドされます。この例ではカバー索引ではないため、FROM変数はrow variableになります。
- このrow variable (
$bag
)は、内側のSELECT式の他の句を実装するイテレータによって参照されます。 - GROUPイテレータは、SELECT式で生成されたレコードを反復処理する内部変数(
$gb-1
)を作成します。 - 下位のGROUPイテレータによって生成される結果セットは部分的です。すべての
fltRouteSrc
グループが含まれるとは限らず、含まれているfltRouteSrc
グループについても、カウントが部分的な合計になることがあります(問合せの実行が停止したときに、特定のfltRouteSrc
の一部の行が取得されていない可能性があるため)。上位のGROUPイテレータは、各RNから部分的な結果を受け取り、最終的なグループ化と集計を実行します。これは下位のGROUPイテレータと同じように動作し、RNからの部分的な結果がなくなるまで動作し続けます。その時点で、完全な最終の結果セットが上位のGROUPイテレータでキャッシュされ、アプリケーションに返されます。 - 上位のGROUPイテレータは、外側のSELECTで生成されたレコードを反復処理する内部変数(
$gb-2
)を作成します。$gb-2
変数には、fltRouteSrc
と、fltRouteSrc
でグループ化されたすべての手荷物の数が含まれます。 - SELECT式では、2つのフィールド(
fltRouteSrc,count(*)
)がフェッチされます。これらは、SELECT式句の2つのフィールド名およびフィールド式に対応します。最初のフィールドについては、フィールド式でFIELD_STEP
イテレータが使用されます。2番目のフィールドは、集計ファンクションcount
です。イテレータFUNC_SUM
は、親イテレータによって生成された結果を反復処理して手荷物の合計数を決定するために使用されます。