joinOrder SPARQL クエリヒント - Amazon Neptune

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

joinOrder SPARQL クエリヒント

SPARQL クエリを送信すると、Amazon Neptune クエリエンジンはクエリの構造を調査します。クエリの各パートの順序を変更し、評価に必要な作業の量とクエリレスポンス時間を最小限にしようとします。

たとえば、一連の接続された 3 つのパターンは通常、指定された順序では評価されません。ヒューリスティックと統計 (個々のパターンの選択性と共有変数で接続される方法など) を使用して順序が変更されます。さらに、サブクエリ、FILTER、複雑な OPTIONAL や MINUS ブロックなど、より複雑なパターンがクエリに含まれている場合、Neptune クエリエンジンは評価の順序を効率的にするために、可能な限りそれらの順序を変更します。

より複雑なクエリでは、Neptune で選択されるクエリの評価順序は常に最適であるとは限りません。たとえば、Neptune では、クエリ評価中に発生するインスタンスデータ固有の特性 (グラフでの power ノードの発生など) を見逃す可能性があります。

データの正確な特性がわかっていて、クエリ実行の順序を手動で指定する場合は、Neptune joinOrder クエリヒントを使用して特定の順序でクエリが評価されるように指定します。

joinOrder SPARQL ヒント構文

joinOrder クエリヒントは、SPARQL クエリに含まれる 3 つのパターンとして指定されます。

わかりやすくするために、次の構文では、クエリに定義されて含まれる hint プレフィックスを使用して Neptune クエリヒント名前空間を指定します。

PREFIX hint: <http://aws.amazon.com/neptune/vocab/v01/QueryHints#> scope hint:joinOrder "Ordered" .
利用可能なスコープ
  • hint:Query

  • hint:Group

クエリヒントスコープの詳細については、「Neptune における SPARQL クエリヒントの範囲。」を参照してください。

joinOrderSPARQL ヒントの例

このセクションでは、joinOrder クエリヒントを使用した場合と使用していない場合に記述されたクエリ、および関連する最適化を示します。

この例では、データセットに次のものが含まれていることを前提としています。

  • Jane を含む 1,000 人に :likes エッジを持つ (「いいね!」した) John という名前の 1 人の人物。

  • John を含む 10 人に :likes エッジを持つ (「いいね!」した) Jane という名前の 1 人の人物。

クエリヒントなし

次の SPARQL クエリは、一連のソーシャルネットワーキングデータから相互に「いいね!」した JohnJane という名前のすべての人物のペアを抽出します。

PREFIX : <https://example.com/> SELECT ?john ?jane { ?person1 :name "Jane" . ?person1 :likes ?person2 . ?person2 :name "John" . ?person2 :likes ?person1 . }

Neptune クエリエンジンは、記述とは異なる順序でステートメントを評価する可能性があります。たとえば、次の順序で評価するように選択される場合があります。

  1. John という名前の人物をすべて検索します。

  2. :likes エッジによって John に接続されているすべての人物を検索します。

  3. Jane という名前の人物でこのセットをフィルタリングします。

  4. :likes エッジによって John に接続されている人物でこのセットをフィルタリングします。

データセットによると、この順序で評価すると 2 番目のステップで 1,000 のエンティティが抽出されます。これは 3 番目のステップで 1 つのノード Jane に絞り込まれます。そして最後のステップで、JaneJohn ノードに対して :likes エッジを持っていると判断されます。

クエリヒント

Jane ノードには発信 :likes エッジが 10 個しかないため、このノードから開始する方が有利です。これにより、2 番目のステップで 1,000 のエンティティを抽出することを回避し、クエリの評価中の作業量を低減できます。

次の例では joinOrder クエリヒントを使用し、クエリの自動結合の順序変更をすべて無効にすることで、Jane ノードとその発信エッジが最初に処理されるようにします。

PREFIX : <https://example.com/> PREFIX hint: <http://aws.amazon.com/neptune/vocab/v01/QueryHints#> SELECT ?john ?jane { hint:Query hint:joinOrder "Ordered" . ?person1 :name "Jane" . ?person1 :likes ?person2 . ?person2 :name "John" . ?person2 :likes ?person1 . }

応用できる現実社会のシナリオとしては、ネットワーク内の人物を「コネクションが多いインフルエンサー」や「コネクションが少ない通常のユーザー」に分類する、ソーシャルネットワークへの応用などが挙げられます。このようなシナリオでは、前述の例のようなクエリで、インフルエンサー (John) の前に通常のユーザー (Jane) が処理されるようになっていることを確認します。

クエリヒントと順序変更

この例をさらに一歩進めることができます。:name 属性が単一のノードに固有であることがわかっている場合は、joinOrder クエリヒントの順序を変更して使用することで、クエリの時間を短縮することができます。このステップでは、最初に一意のノードが抽出されるようにします。

PREFIX : <https://example.com/> PREFIX hint: <http://aws.amazon.com/neptune/vocab/v01/QueryHints#> SELECT ?john ?jane { hint:Query hint:joinOrder "Ordered" . ?person1 :name "Jane" . ?person2 :name "John" . ?person1 :likes ?person2 . ?person2 :likes ?person1 . }

この場合、各ステップで以下の単一のアクションへのクエリを減らすことができます。

  1. :name Jane を持つ 1 人の人物のノードを検索します。

  2. :name John を持つ 1 人の人物のノードを検索します。

  3. 最初のノードが 2 番目のノードに :likes エッジで接続されていることを確認します。

  4. 2 番目のノードが最初のノードに :likes エッジで接続されていることを確認します。

重要

間違った順序を選択した場合、joinOrder クエリヒントのパフォーマンスが大幅に低下する可能性があります。たとえば、前述の例は :name 属性が一意でない場合、非効率的です。100 ノードすべての名前が Jane で 1,000 ノードすべての名前が John の場合、クエリで 1,000 * 100 (100,000) ペアの :likes エッジを確認することになります。