Best practice per le query del grafico

Questo documento descrive le best practice per ottimizzare le query BigQuery Graph.

Inizia l'attraversamento del percorso dai nodi a bassa cardinalità

Per mantenere piccoli i set di risultati intermedi e velocizzare l'esecuzione delle query, scrivi le query grafiche in modo che l'attraversamento del percorso inizi dai nodi con cardinalità inferiore, indipendentemente dalla direzione dell'attraversamento del percorso. Le seguenti istruzioni MATCH utilizzano i filtri delle proprietà per ridurre il numero di nodi iniziali possibili anziché calcolare tutte le corrispondenze e poi filtrare:

MATCH (p:Person {id: 10})-[own:Owns]->(a:Account)
MATCH (a:Account WHERE balance > 10)<-[own:Owns]-(p:Person)

Ciò è particolarmente importante per le query sul percorso quantificato:

MATCH (p:Person {id: 10})-[own:Owns]->{1,3}(a:Account)

Utilizza la sintassi ANY o ANY SHORTEST per i controlli di connettività

Le query sui percorsi quantificati possono restituire percorsi duplicati tra i nodi di origine e i nodi di destinazione. Se il tuo obiettivo è verificare la connettività e non hai bisogno di tutti i percorsi possibili, utilizza ANY o ANY SHORTEST per ridurre i calcoli ridondanti e migliorare l'efficienza della ricerca dei percorsi. Ad esempio, la seguente istruzione MATCH utilizza ANY SHORTEST per mantenere un solo percorso tra ogni coppia di nodi:

MATCH ANY SHORTEST (a1:Account)-[t:Transfers]->{1,3}(a2:Account)

Utilizzare l'attraversamento del percorso direzionale

Gli schemi BigQuery Graph sono direzionali, il che significa che ogni arco ha un nodo di origine e un nodo di destinazione. Sebbene la sintassi delle query del grafico consenta l'attraversamento del percorso in qualsiasi direzione (ad esempio, -[edge]-), ti consigliamo di utilizzare l'attraversamento del percorso direzionale (ad esempio, -[edge]-> o <-[edge]-) per prestazioni migliori. L'attraversamento di qualsiasi percorso direzionale potrebbe causare una perdita di prestazioni.

La seguente istruzione MATCH utilizza l'attraversamento del percorso in qualsiasi direzione:

-- Avoid.
MATCH (a1:Account {id: 7})-[t:Transfers]-(a2:Account)

Combina invece due spostamenti direzionali con UNION ALL:

MATCH (a1:Account {id: 7})-[t:Transfers]->(a2:Account)
...
UNION ALL
...
MATCH (a1:Account  {id: 7})<-[t:Transfers]-(a2:Account)

Specificare le etichette in modo esplicito

Se le etichette di nodi o archi vengono omesse in una query, BigQuery Graph enumera tutte le etichette di nodi e archi idonee. Questa enumerazione potrebbe causare la scansione di più etichette del necessario. Per evitarlo, specifica le etichette per tutti i nodi e gli archi nella query, se possibile.

Ad esempio, la seguente query specifica le etichette Account e Transfers:

GRAPH graph_db.FinGraph
MATCH (a1:Account)-[t:Transfers]->(a2:Account)
RETURN COUNT(*) AS num_transfers;

Evita di omettere le etichette, perché potrebbero essere analizzate altre relazioni non necessarie tra i nodi. Nella seguente query, a1 può rappresentare un account o una persona e t può rappresentare un trasferimento o la proprietà di un account.

GRAPH graph_db.FinGraph
MATCH (a1)-[t]->(a2)
RETURN COUNT(*) AS num_transfers;

Preferisci una singola dichiarazione MATCH

BigQuery Graph ti consente di includere più istruzioni MATCH in una singola query del grafico. Queste istruzioni sono collegate da variabili dichiarate più volte che rappresentano lo stesso nodo o lo stesso arco. Tuttavia, l'utilizzo di più istruzioni MATCH può ridurre i vantaggi della cardinalità tra le istruzioni. Se possibile, utilizza una singola istruzione MATCH per un rendimento migliore.

Ad esempio, le seguenti query sono equivalenti, ma la prima ha un rendimento migliore perché utilizza una singola istruzione MATCH:

-- 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;

Limita gli archi attraversati dai nodi ad alta cardinalità

Quando esegui query sui grafici, alcuni nodi possono avere un numero significativamente maggiore di archi in entrata o in uscita rispetto ad altri nodi. Questi nodi ad alta cardinalità sono a volte chiamati super nodi o nodi hub. I super nodi possono causare problemi di prestazioni perché i relativi attraversamenti potrebbero comportare l'elaborazione di grandi quantità di dati, il che porta a una distorsione dei dati e a tempi di esecuzione lunghi.

Per ottimizzare una query di un grafico con supernodi, utilizza la funzione ROW_NUMBER() all'interno di una clausola FILTER o WHERE in MATCH per limitare il numero di archi che la query attraversa da o verso un nodo. Questa tecnica è particolarmente utile quando non è necessaria un'enumerazione completa di tutte le connessioni da o verso un supernodo.

Ad esempio, se alcuni account in FinGraph hanno un numero elevato di transazioni, puoi utilizzare ROW_NUMBER() per limitare il numero di archi Transfers da considerare per ogni Account ed evitare una query inefficiente:

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;

Esegui il campionamento di nodi o archi intermedi nelle query multihop

Puoi anche migliorare l'efficienza delle query utilizzando ROW_NUMBER() per campionare i nodi intermedi nelle query multihop. Questa tecnica migliora l'efficienza limitando il numero di percorsi che la query considera per ogni nodo intermedio. Per farlo, suddividi una query multi-hop in più istruzioni MATCH separate da NEXT e applica ROW_NUMBER() a metà percorso in cui devi campionare:

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;

Passaggi successivi