例2: 索引スキャンと索引条件が含まれる問合せ計画でのカバー索引の使用

州(state)がCAで収入(income)が2000より多いユーザーのID (id)と収入(income)をフェッチします。
SELECT id, income FROM Users u WHERE u.address.state = "CA" AND income > 2000
問合せ実行計画:
{
  "iterator kind" : "RECEIVE",
  "distribution kind" : "ALL_SHARDS",
  "input iterator" :
  {
    "iterator kind" : "SELECT",
    "FROM" :
    {
      "iterator kind" : "TABLE",
      "target table" : "users",
      "row variable" : "$$u",
      "index used" : "idx_state_city_income",
      "covering index" : true,
      "index row variable" : "$$u_idx",
      "index scans" : [
        {
          "equality conditions" : {"address.state":"CA"},
          "range conditions" : {}
        }
      ],
      "index filtering predicate" :
      {
        "iterator kind" : "GREATER_THAN",
        "left operand" :
        {
          "iterator kind" : "FIELD_STEP",
          "field name" : "income",
          "input iterator" :
          {
            "iterator kind" : "VAR_REF",
            "variable" : "$$u_idx"
          }
        },
        "right operand" :
        {
          "iterator kind" : "CONST",
          "value" : 2000
        }
      }
    },
    "FROM variable" : "$$u_idx",
    "SELECT expressions" : [
      {
        "field name" : "id",
        "field expression" :
        {
          "iterator kind" : "FIELD_STEP",
          "field name" : "#id",
          "input iterator" :
          {
            "iterator kind" : "VAR_REF",
            "variable" : "$$u_idx"
          }
        }
      },
      {
        "field name" : "income",
        "field expression" :
        {
          "iterator kind" : "FIELD_STEP",
          "field name" : "income",
          "input iterator" :
          {
            "iterator kind" : "VAR_REF",
            "variable" : "$$u_idx"
          }
        }
      }
    ]
  }
}
問合せ実行計画の説明:
  • この問合せ計画のルート・イテレータは、SELECTイテレータである単一の子(入力イテレータ)がある、RECEIVEイテレータです。この例でのRECEIVEイテレータの唯一のプロパティは、値がALL_SHARDSであるdistribution kindです。
  • ここでは索引idx_state_city_incomeが使用されています。また、SELECT式内のすべてのフィールドは索引エントリの使用によってのみフェッチ可能であるため、これはカバー索引です。
  • 索引スキャン・プロパティには、実行する索引スキャンを定義する、開始条件と停止条件が含まれています。
    "index scans" : [
       {
          "equality conditions" : {"address.state":"CA"},
          "range conditions" : {}
       }
    ]
    この例では、1つの索引スキャンのみが実行されます。その条件は、その問合せからのu.address.state = "CA"という条件に対応しています。具体的に述べると、開始索引エントリで、address.stateフィールドの値がCAである必要があります。後続のすべてのエントリでそのaddress.stateフィールドの値がCAである必要があり、state値が異なるエントリが検出されるとすぐにスキャンが停止されます。問合せにはincomeの範囲条件が含まれていますが、この条件は索引スキャンの範囲条件として表示されません。これは、索引定義内のincomeフィールドの前にあるaddress.cityフィールドに等価条件がなく、その結果、income条件を使用してスキャンの境界を判断できないためです。かわりに、この索引スキャンによって生成されるすべての索引エントリに適用するindex filtering predicateとして、income条件を使用できます。
  • index filtering predicateでは、incomeフィールドのフィルタ基準が評価されます。より大演算子を使用して、フィルタ条件が評価されます。
    "index filtering predicate" :
    {
       "iterator kind" : "GREATER_THAN",
       "left operand" :
       {
          "iterator kind" : "FIELD_STEP",
          "field name" : "income",
          "input iterator" :
          {
             "iterator kind" : "VAR_REF",
             "variable" : "$$u_idx"
          }
       },
       "right operand" :
       {
          "iterator kind" : "CONST",
          "value" : 2000
       }
    }   
  • index row variableは$$u_idxであり、これは、TABLEイテレータによって生成されるすべての索引エントリを対象とする、変数の名前です。索引スキャンによって新しい索引エントリが生成されるたびに、$$u_idx変数がそのエントリにバインドされます。
  • FROMイテレータがTABLEイテレータである場合、FROM variableは、TABLEイテレータのindex row variableまたはrow variableのどちらか(使用されている索引がカバーかどうかで異なる)と同じになります。この例では、SELECT式内のすべてのフィールドは索引エントリの使用によってのみ評価可能であるため索引はカバーであり、FROM variableはindex row variable ($$u_idx)と同じになります。
  • このindex row variable ($$u_idx)は、SELECT式の他の句を実装するイテレータによって参照されます。
  • このSELECT式では、2つのフィールド(idおよびincome)がフェッチされます。これらは、SELECT式の句にある2つのフィールド名およびフィールド式に対応しています。
    {
       "field name" : "id",
       "field expression" :
       {
          "iterator kind" : "FIELD_STEP",
          "field name" : "#id",
          "input iterator" :
          {
             "iterator kind" : "VAR_REF",
             "variable" : "$$u_idx"
          }
       }
    }
    このSELECT式によってフェッチされるフィールドごとに、フィールド式がFIELD_STEPイテレータによって計算されます。FIELD_STEPイテレータでは、その入力イテレータで生成されたレコードからフィールド(前述のid)の値が抽出され返されます。このSELECT式でフェッチされるフィールドごとに同じことが実行されます。