Optimieren der GQL-Abfrageleistung für Diagramme in Microsoft Fabric

Dieser Artikel enthält Anleitungen zum Schreiben von GQL-Abfragen (Graph Query Language), die beim Arbeiten mit Graph in Microsoft Fabric vorhersehbar und effizient ausgeführt werden. Die Empfehlungen basieren auf dem aktuellen Plattformverhalten und dokumentierten Einschränkungen.

Für feste Grenzwerte für die Größe von Diagrammen, die Ergebnisgröße und das Abfragetimeout finden Sie unter "Aktuelle Einschränkungen". Mehrere Empfehlungen in diesem Artikel beziehen sich auch auf die Art und Weise, wie Sie Ihr Diagrammschema entwerfen. Weitere Informationen finden Sie unter Entwerfen eines Diagrammschemas.

Platziere Filter entsprechend ihrer Semantik

Platziere ein Prädikat in ein Graphenmuster, wenn es definiert, welcher Knoten oder welche Kante am Match teilnehmen darf. Verwenden Sie eine Bedingung auf Anweisungsebene MATCH ... WHERE, um die abgeschlossene Übereinstimmung nachzufiltern, oder eine separate FILTER Anweisung, wenn das Prädikat auf die von einer früheren Anweisung erzeugte Zeile zutrifft.

Verwenden Sie zum Beispiel Klauseln auf Musterebene WHERE für Bedingungen für die übereinstimmenden Knoten:

MATCH (p:Person WHERE p.birthday < 19940101)-[:workAt]->(c:Company WHERE c.id > 1000)
RETURN p.firstName, p.lastName, c.name

Ein separates FILTER kann dieselbe Bedingung nach einer gewöhnlichen obligatorischen Übereinstimmung ausdrücken, die die Standard-Pfadsuche mit ALL verwendet:

MATCH (p:Person)-[:workAt]->(c:Company)
FILTER p.birthday < 19940101 AND c.id > 1000
RETURN p.firstName, p.lastName, c.name

Der Abfrageoptimierer kann beim Scannen äquivalente Prädikate anwenden, wobei dies die Abfragesemantik bewahrt, sodass die Inline-Syntax nicht automatisch schneller ist. Wählen Sie das Formular, das ausdrückt, wann die Bedingung gilt.

Die Prädikatenplatzierung kann die Ergebnisse mit ANY SHORTESTverändern. Inline-Prädikate schränken die Pfade ein, die für die Auswahl des kürzesten Pfads zugelassen sind. Ein WHERE auf Anweisungsebene oder ein nachfolgendes FILTER greift erst nach der Pfadauswahl, sodass ein ausgewählter kürzester Pfad entfernt werden kann, ohne dass stattdessen ein längerer Pfad ausgewählt wird. Informationen zur aktuellen MATCH ... WHERE Einschränkung und zu einem zuverlässigen Platzierungsmuster finden Sie unter Prädikate vor oder nach der Pfadauswahl platzieren.

Auch die Platzierung bei OPTIONAL MATCH ist wichtig, wobei ein inline WHERE die optionale Übereinstimmung einschränkt, ein nachfolgendes FILTER jedoch die null-erweiterte Zeile entfernen kann.

Tipp

Stellen Sie sich die Musterebene WHERE analog zu einer SQL-Bedingung JOIN ... ON vor. Sie beschreibt, welche Übereinstimmungen qualifizieren, anstatt die resultierende Zeile danach zu filtern.

Nur die benötigten Eigenschaften zurückgeben

Geben Sie nur die Knoten- und Edgeeigenschaften zurück, die für Ihr Szenario erforderlich sind. Vermeiden Sie die Rückgabe vollständiger Knoten oder die Verwendung RETURN * , wenn Sie nur eine Teilmenge von Eigenschaften benötigen.

Das Auswählen unnötiger Eigenschaften erhöht die Datenlese-, Serialisierungskosten und Antwortgröße. Während der Graphmodellierung wählt man nur die Quellspalten aus, die als Knotentypeigenschaften benötigt werden.

Empfohlen: Schmale Projektion.

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name

Vermeide: Zurückgabe von vollständigen Knoten.

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN *

Hinweis

Fügen Sie während der Diagrammmodellierung nur Knotentypeigenschaften hinzu, wenn sie für Abfragen oder Analysen erforderlich sind. Weniger Eigenschaften pro Knoten reduzieren sowohl Speicher- als auch Abfragekosten.

Begrenzen der Ergebnismenge

Wenden Sie LIMIT oder andere Begrenzungsbedingungen beim Abfragen von Knoten oder Beziehungen an, die möglicherweise eine hohe Kardinalität aufweisen. Ungebundene Graphen-Matches können sehr große Ergebnismengen erzeugen, die die Grenzen der Plattform erreichen.

Empfohlen: Begrenzte Ergebnisse.

MATCH (p:Person)-[:knows]->(friend:Person)
RETURN p.firstName, friend.firstName
LIMIT 1000

Vermeide: Unbegrenzten Match mit hoher Kardinalität.

MATCH (p:Person)-[:knows]->(friend:Person)
RETURN p.firstName, friend.firstName

Von Bedeutung

Graph verkürzt Anfrageantworten, deren interne binäre Darstellung 64 MB übersteigt. Eine verkürzte Antwort enthält einen zusätzlichen Status mit öffentlichem Code 01000 und dem kanonischen GQLSTATUS 01M11. Verwenden Sie Filter, schmale Projektionen und LIMIT um die Ergebnisgröße zu reduzieren. Weitere Informationen finden Sie unter Aktuelle Einschränkungen.

Halten Sie Traversals flach und gezielt

Vermeiden Sie tief geschachtelte oder hochkomplexe Diagrammmuster. Verwenden Sie einfache, gezielte Durchgänge, die eine bestimmte Frage direkt beantworten. Jeder zusätzliche Hop in einem variablen Längenmuster kann die Anzahl der von der Engine ausgewerteten Pfade exponentiell erhöhen, insbesondere in dicht verbundenen Graphen.

Empfohlen: Enge Grenzen.

-- Use the narrowest hop range that answers your question
MATCH (p:Person)-[:knows]->{1,3}(friend:Person)
RETURN p.firstName, friend.firstName
LIMIT 1000

Vermeiden: Einen großen Verfahrbereich ohne klaren Bedarf.

-- A wider range on a dense graph is more expensive
MATCH (p:Person)-[:knows]->{1,8}(friend:Person)
RETURN *

Von Bedeutung

Der visuelle Abfrage-Builder begrenzt variable Pfade auf acht Sprünge, aber diese Benutzeroberflächenbeschränkung gilt nicht für GQL im Code-Editor. Nutze die engste Grenze, die dein Szenario zulässt, weil eine größere Reichweite mehr Wege abdecken kann.

Verwenden Sie TRAIL, wenn Wege keine Kanten wiederholen dürfen

Verwenden Sie TRAIL den Pfadmodus, wenn ein gültiger Pfad eine Kante nicht wiederholen darf. In Graphen mit Zyklen kann diese Einschränkung auch die Anzahl der passenden Pfade im Vergleich zum Standardmodus WALK verringern.

-- TRAIL prevents revisiting the same :knows edge
MATCH TRAIL (src:Person)-[:knows]->{1,4}(dst:Person)
WHERE src.firstName = 'Alice' AND dst.firstName = 'Bob'
RETURN count(*) AS numPaths

Ohne TRAIL, kann dieselbe Abfrage auf einem zyklischen Graphen Pfade zurückgeben, die eine Kante wiederholen. Verwenden Sie den Modus, der zur erforderlichen Pfadsemantik passt, anstatt es als allgemeine Leistungsoptimierung zu behandeln TRAIL .

Ein unbeschränktes ALL WALK Muster wird nicht unterstützt, weil Zyklen unendlich viele Pfade erzeugen können. Obwohl unbeschränkte TRAIL, SIMPLE, und ACYCLIC Muster enden, können sie dennoch viele Wege aufzählen. Verwenden Sie eine endliche obere Schranke, es sei denn, die Abfrage erfordert eine unbeschränkte Durchquerung.

Verwenden freigegebener Variablen für effiziente Verknüpfungen

Wenn eine Abfrage Daten aus mehreren Beziehungen erfordert, verwenden Sie eine freigegebene Variable, um Muster für dieselbe Entität zu verknüpfen. Ohne eine freigegebene Variable können Muster ein kartesisches Produkt erzeugen – jede Kombination von Übereinstimmungen aus beiden Mustern – was zu einem viel größeren Resultset führt.

Empfohlen: Die freigegebene Variable p verknüpft die Muster.

-- Single shared variable ensures an efficient join
MATCH (p:Person)-[:workAt]->(c:Company),
      (p)-[:isLocatedIn]->(city:City)
RETURN p.firstName, c.name AS company, city.name AS city
LIMIT 1000

Vermeide: Unabhängige Muster ohne freigegebene Variable.

-- Without a shared variable, this produces a cartesian product
MATCH (p1:Person)-[:workAt]->(c:Company),
      (p2:Person)-[:isLocatedIn]->(city:City)
RETURN p1.firstName, c.name, p2.firstName, city.name

Ein kartesisches Produkt paart jedes Ergebnis aus einem Muster mit jedem Ergebnis aus dem anderen. Wenn Person-workAt->Company 1.000 Zeilen und Person-isLocatedIn->City 500 Zeilen übereinstimmen, gibt die Abfrage 1.000 × 500 = 500.000 Zeilen zurück. Durch das Hinzufügen einer freigegebenen Variablen wird die Verknüpfung eingeschränkt, sodass nur übereinstimmende Paare zurückgegeben werden.

Filtern Sie nach Schlüsseleigenschaften bei der Identifizierung von Knoten

Definiere Knotenschlüssel-Constraints , um Knoten eindeutig zu identifizieren und die Datenintegrität durchzusetzen. Wenn Sie einen bestimmten Knoten benötigen, fügen Sie dessen Schlüsseleigenschaft in das Musterprädikat ein, um zu vermeiden, dass nicht zusammenhängende Knoten übereinstimmen.

Wenn dein Diagrammtyp beispielsweise id als Schlüssel für Person Knoten definiert:

CONSTRAINT person_pk
  FOR (n:Person) REQUIRE n.id IS KEY

Filtern Sie dann nach id, wenn Sie diese Person benötigen:

MATCH (p:Person WHERE p.id = 12345)-[:workAt]->(c:Company)
RETURN p.firstName, c.name

Ohne den Filter entspricht die Abfrage jedem Person-Knoten, bevor sie workAt-Kanten durchläuft:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, c.name

Tipp

Eine zentrale Einschränkung begründet Identität und Einzigartigkeit. An sich garantiert es keinen bestimmten physischen Suchvorgang oder Abfrageplan.

Auswählen geeigneter Datentypen

Wählen Sie den Datentyp, der die Werte und die vorgesehenen Operationen jeder Eigenschaft repräsentiert. Verwenden Sie zum Beispiel einen numerischen Typ für Werte, die Sie numerisch berechnen oder vergleichen, anstatt formatierte Zahlen als Zeichenketten zu speichern.

Unterstützte Datentypen finden Sie unter "Aktuelle Einschränkungen" – Datentypen und unterstützte Eigenschaftstypen.

Rufen Sie nach Möglichkeit verwandte Entitäten in einem einzelnen Diagrammmuster ab, anstatt separate Abfragen auszugeben, die die gleichen Kanten unabhängig voneinander durchlaufen. Durch die Kombination von Traversierungen werden redundante Musterabgleiche vermieden und das N+1-Abfrageproblem verhindert, bei dem eine erste Abfrage eine separate Abfrage für jede Ergebniszeile auslöst.

Empfohlen: Einzelnes kombiniertes Muster.

MATCH (c:Customer)-[:purchases]->(o:`Order`)-[:`contains`]->(product:`Product`)
RETURN c.fullName, o, product.productName
LIMIT 1000

Vermeide: Zwei separate Abfragen, die denselben Customer → Order Rand durchlaufen.

-- Query 1: fetch 100 orders
MATCH (c:Customer)-[:purchases]->(o:`Order`)
RETURN c.fullName, o
LIMIT 100

-- Query 2: repeat for each returned order, substituting its key value
MATCH (o:`Order` WHERE o.SalesOrderDetailID_K = 12345)-[:`contains`]->(product:`Product`)
RETURN o, product.productName

Testen von Abfragen mit realistischen Datenvolumes

Abfragen, die für kleine Datasets gut funktionieren, werden möglicherweise nicht linear skaliert. Testen Sie Ihre Abfragen mit Datenvolumes, die Ihre erwartete Produktionsauslastung darstellen.

  • Bevorzugen Sie konservative Abfrage-Shapes, die Filter und Grenzwerte enthalten.
  • Vermeiden Sie explorative "alles zurückgeben" Abfragen gegen große Grafen.
  • Überwachen Sie die Abfragedauer relativ zum Zeitlimit von 20 Minuten.