Best Practices für Graphabfragen
In diesem Dokument werden Best Practices zur Optimierung Ihrer BigQuery-Graphabfragen beschrieben.
Path Traversal von Knoten mit niedriger Kardinalität starten
Damit Zwischenergebnissätze klein bleiben und die Abfrageausführung beschleunigt wird, sollten Sie Ihre Graphabfragen so schreiben, dass die Pfadtraversierung von Knoten mit niedriger Kardinalität aus startet, unabhängig von der Richtung der Pfadtraversierung. In den folgenden MATCH-Anweisungen werden Eigenschaftsfilter verwendet, um die Anzahl der möglichen Startknoten zu reduzieren, anstatt alle Übereinstimmungen zu berechnen und dann zu filtern:
MATCH (p:Person {id: 10})-[own:Owns]->(a:Account)
MATCH (a:Account WHERE balance > 10)<-[own:Owns]-(p:Person)
Das ist besonders wichtig für quantifizierte Pfadabfragen:
MATCH (p:Person {id: 10})-[own:Owns]->{1,3}(a:Account)
`ANY`- oder `ANY SHORTEST`-Syntax für Konnektivitätstests verwenden
Quantifizierte Pfadabfragen können doppelte Pfade zwischen Quell- und Zielknoten zurückgeben. Wenn Sie die Konnektivität prüfen möchten und nicht
alle möglichen Pfade benötigen, verwenden Sie ANY oder ANY SHORTEST, um redundante
Berechnungen zu reduzieren und die Effizienz der Pfadsuche zu verbessern. In der folgenden MATCH-Anweisung wird beispielsweise ANY SHORTEST verwendet, um nur einen Pfad zwischen jedem Knotenpaar beizubehalten:
MATCH ANY SHORTEST (a1:Account)-[t:Transfers]->{1,3}(a2:Account)
Gerichtete Path Traversal verwenden
BigQuery-Graphschemata sind gerichtet. Das bedeutet, dass jede Edge einen Quell- und einen Zielknoten hat. Obwohl die Graphabfragesyntax die Pfadtraversierung in jeder Richtung zulässt (z. B. -[edge]-), empfehlen wir für eine bessere Leistung die gerichtete Pfadtraversierung (z. B. -[edge]-> oder
<-[edge]-). Die Pfadtraversierung in beliebiger Richtung kann zu Leistungseinbußen führen.
Die folgende MATCH-Anweisung verwendet eine Path Traversal in beliebiger Richtung:
-- Avoid.
MATCH (a1:Account {id: 7})-[t:Transfers]-(a2:Account)
Kombinieren Sie stattdessen zwei gerichtete Traversierungen mit UNION ALL:
MATCH (a1:Account {id: 7})-[t:Transfers]->(a2:Account)
...
UNION ALL
...
MATCH (a1:Account {id: 7})<-[t:Transfers]-(a2:Account)
Labels explizit angeben
Wenn in einer Abfrage Knoten- oder Edge-Labels ausgelassen werden, zählt BigQuery Graph alle infrage kommenden Knoten- und Edge-Labels auf. Bei dieser Aufzählung werden möglicherweise mehr Labels gescannt als erforderlich. Geben Sie daher nach Möglichkeit Labels für alle Knoten und Edges in Ihrer Abfrage an.
In der folgenden Abfrage werden beispielsweise die Labels Account und Transfers angegeben:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[t:Transfers]->(a2:Account)
RETURN COUNT(*) AS num_transfers;
Vermeiden Sie es, Labels auszulassen, da sonst möglicherweise andere unnötige Beziehungen zwischen Knoten gescannt werden. In der folgenden Abfrage kann a1 ein Konto oder eine
Person darstellen und t kann für eine Überweisung oder ein Kontoeigentum stehen.
GRAPH graph_db.FinGraph
MATCH (a1)-[t]->(a2)
RETURN COUNT(*) AS num_transfers;
Eine einzelne MATCH-Anweisung bevorzugen
Mit BigQuery Graph können Sie mehrere MATCH-Anweisungen in eine einzelne Graphabfrage einfügen. Diese Anweisungen sind durch mehrfach deklarierte Variablen verbunden, die denselben Knoten oder dieselbe Edge darstellen. Die Verwendung mehrerer MATCH-Anweisungen kann jedoch die Vorteile der Kardinalität über Anweisungen hinweg verringern. Verwenden Sie nach Möglichkeit eine einzelne MATCH-Anweisung, um die Leistung zu verbessern.
Die folgenden Abfragen sind beispielsweise gleichwertig, aber die erste ist leistungsstärker, da sie eine einzelne MATCH-Anweisung verwendet:
-- Preferred syntax.
GRAPH graph_db.FinGraph
MATCH
(p:Person {id: 1})-[o:Owns]->
(a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
-- Avoid this syntax.
GRAPH graph_db.FinGraph
MATCH (p:Person {id: 1})-[o:Owns]->(a:Account)
MATCH (a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
Traversierte Edges von Knoten mit hoher Kardinalität begrenzen
Beim Abfragen von Graphen kann die Anzahl der eingehenden oder ausgehenden Edges für einige Knoten deutlich höher sein als für andere. Diese Knoten mit hoher Kardinalität werden manchmal als Superknoten oder Hubknoten bezeichnet. Superknoten können Leistungsprobleme verursachen, da bei Traversierungen durch sie große Datenmengen verarbeitet werden müssen, was zu Datenverzerrungen und langen Ausführungszeiten führt.
Um eine Abfrage eines Graphen mit Superknoten zu optimieren, verwenden Sie die
ROW_NUMBER() Funktion
in einer FILTER Klausel oder WHERE Klausel in MATCH, um die
Anzahl der Edges zu begrenzen, die die Abfrage von oder zu einem Knoten traversiert. Diese Methode ist besonders nützlich, wenn Sie keine vollständige Aufzählung aller Verbindungen von oder zu einem Superknoten benötigen.
Wenn beispielsweise einige Konten in FinGraph eine große Anzahl von Transaktionen haben, können Sie mit ROW_NUMBER() die Anzahl der Transfers-Edges begrenzen, die für jedes Account berücksichtigt werden sollen, und so eine ineffiziente Abfrage vermeiden:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers WHERE e1 IN {
GRAPH graph_db.FinGraph
-- Sample 5 edges per source node
MATCH -[selected_e:Transfers]->
FILTER ROW_NUMBER() OVER (
PARTITION BY SOURCE_NODE_ID(selected_e)) < 5
RETURN selected_e
}]->{1,3}(a2:Account)
RETURN COUNT(*) AS cnt;
Zwischenknoten oder -edges in Abfragen mit mehreren Schritten abtasten
Sie können die Abfrageeffizienz auch verbessern, indem Sie ROW_NUMBER() verwenden, um Zwischenknoten in Abfragen mit mehreren Schritten abzutasten. Diese Methode verbessert die Effizienz, indem sie die Anzahl der Pfade begrenzt, die die Abfrage für jeden Zwischenknoten berücksichtigt. Dazu teilen Sie eine Abfrage mit mehreren Schritten in mehrere MATCH-Anweisungen auf, die durch NEXT getrennt sind, und wenden ROW_NUMBER() am Mittelpunkt an, an dem Sie eine Stichprobe erstellen möchten:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers]->(a2:Account)
-- Sample 5 destination nodes per a1 source node
FILTER ROW_NUMBER() OVER (PARTITION BY ELEMENT_ID(a1)) < 5
RETURN a1, a2
NEXT
MATCH (a2)-[e2:Transfers]->(a3:Account)
RETURN a1.id AS src_id, a2.id AS mid_id, a3.id AS dst_id;
Nächste Schritte
- Weitere Informationen zum Schreiben von Graphabfragen finden Sie in der Abfrageübersicht.
- Weitere Informationen zum Entwerfen Ihres Graphschemas.