翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
SPARQL joinOrder
クエリヒント
SPARQL クエリを送信すると、Amazon Neptune クエリエンジンはクエリの構造を調査します。クエリの各パートの順序を変更し、評価に必要な作業の量とクエリレスポンス時間を最小限にしようとします。
たとえば、一連の接続された 3 つのパターンは通常、指定された順序では評価されません。ヒューリスティックと統計 (個々のパターンの選択性と共有変数で接続される方法など) を使用して順序が変更されます。さらに、クエリにサブクエリ、FILTERs、複雑な Word または 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 クエリヒントの範囲」を参照してください。
joinOrder
SPARQLヒントの例
このセクションでは、joinOrder
クエリヒントを使用した場合と使用していない場合に記述されたクエリ、および関連する最適化を示します。
この例では、データセットに次のものが含まれていることを前提としています。
Jane
を含む 1,000 人に:likes
エッジを持つ (「いいね!」した)John
という名前の 1 人の人物。John
を含む 10 人に:likes
エッジを持つ (「いいね!」した)Jane
という名前の 1 人の人物。
クエリヒントなし
次の SPARQL クエリは、ソーシャルネットワーキングデータのセットから、 と という名前のユーザーJohn
と、互いに好きJane
であるユーザーのすべてのペアを抽出します。
PREFIX : <https://example.com/> SELECT ?john ?jane { ?person1 :name "Jane" . ?person1 :likes ?person2 . ?person2 :name "John" . ?person2 :likes ?person1 . }
Neptune クエリエンジンは、記述とは異なる順序でステートメントを評価する可能性があります。たとえば、次の順序で評価するように選択される場合があります。
John
という名前の人物をすべて検索します。:likes
エッジによってJohn
に接続されているすべての人物を検索します。Jane
という名前の人物でこのセットをフィルタリングします。:likes
エッジによってJohn
に接続されている人物でこのセットをフィルタリングします。
データセットによると、この順序で評価すると 2 番目のステップで 1,000 のエンティティが抽出されます。これは 3 番目のステップで 1 つのノード Jane
に絞り込まれます。そして最後のステップで、Jane
も John
ノードに対して :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 . }
この場合、各ステップで以下の単一のアクションへのクエリを減らすことができます。
:name
Jane
を持つ 1 人の人物のノードを検索します。:name
John
を持つ 1 人の人物のノードを検索します。最初のノードが 2 番目のノードに
:likes
エッジで接続されていることを確認します。2 番目のノードが最初のノードに
:likes
エッジで接続されていることを確認します。
重要
間違った順序を選択した場合、joinOrder
クエリヒントのパフォーマンスが大幅に低下する可能性があります。たとえば、前述の例は :name
属性が一意でない場合、非効率的です。100 ノードすべての名前が Jane
で 1,000 ノードすべての名前が John
の場合、クエリで 1,000 * 100 (100,000) ペアの :likes
エッジを確認することになります。