Questo documento descrive le best practice per l'ottimizzazione delle prestazioni delle query Spanner Graph, che includono le seguenti ottimizzazioni:
- Evita una scansione completa della tabella di input per nodi e archi.
- Ridurre la quantità di dati che la query deve leggere dallo spazio di archiviazione.
- Riduci le dimensioni dei dati intermedi.
Inizia dai nodi con cardinalità inferiore
Scrivi l'attraversamento del percorso in modo che inizi con i nodi a cardinalità inferiore. Questo approccio mantiene piccolo il set di risultati intermedi e velocizza l'esecuzione delle query.
Ad esempio, le seguenti query hanno la stessa semantica:
Attraversamento del bordo in avanti:
GRAPH FinGraph MATCH (p:Person {name:"Alex"})-[:Owns]->(a:Account {is_blocked: true}) RETURN p.id AS person_id, a.id AS account_id;Attraversamento del bordo inverso:
GRAPH FinGraph MATCH (a:Account {is_blocked:true})<-[:Owns]-(p:Person {name: "Alex"}) RETURN p.id AS person_id, a.id AS account_id;
Supponendo che il numero di persone con il nome Alex sia inferiore al numero di account bloccati, ti consigliamo di scrivere questa query nella traversata degli archi in avanti.
Iniziare dai nodi con cardinalità inferiore è particolarmente importante per l'attraversamento di percorsi di lunghezza variabile. L'esempio seguente mostra il modo consigliato per trovare gli account che si trovano a tre trasferimenti da un determinato account.
GRAPH FinGraph
MATCH (:Account {id: 7})-[:Transfers]->{1,3}(a:Account)
RETURN a.id;
Specificare tutte le etichette per impostazione predefinita
Spanner Graph deduce i nodi e le etichette degli archi qualificanti se le etichette vengono omesse. Ti consigliamo di specificare le etichette per tutti i nodi e gli archi, se possibile, perché questa inferenza potrebbe non essere sempre possibile e potrebbe causare la scansione di più etichette del necessario.
Singola istruzione MATCH
L'esempio seguente trova gli account collegati da un massimo di tre trasferimenti dall'account specificato:
GRAPH FinGraph
MATCH (src:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id;
Nelle istruzioni MATCH
Specifica le etichette su nodi e archi quando si riferiscono allo stesso elemento, ma si trovano
in istruzioni MATCH.
L'esempio seguente mostra questo approccio consigliato:
GRAPH FinGraph
MATCH (acct:Account {id: 7})-[:Transfers]->{1,3}(other_acct:Account)
RETURN acct, COUNT(DISTINCT other_acct) AS related_accts
GROUP BY acct
NEXT
MATCH (acct:Account)<-[:Owns]-(p:Person)
RETURN p.id AS person, acct.id AS acct, related_accts;
Utilizzare IS_FIRST per ottimizzare le query
Puoi utilizzare la funzione
IS_FIRST
per migliorare il rendimento delle query campionando i bordi e limitando gli attraversamenti
nei grafici. Questa funzione consente di gestire i nodi con cardinalità elevata e ottimizzare
le query multihop.
Se la dimensione del campione specificata è troppo piccola, la query potrebbe non restituire dati. Per questo motivo, potresti dover provare diverse dimensioni del campione per trovare l'equilibrio ottimale tra i dati restituiti e il miglioramento delle prestazioni delle query.
Questi esempi di IS_FIRST utilizzano FinGraph, un grafico finanziario con Account nodi
e Transfers archi per i trasferimenti di denaro. Per creare FinGraph e utilizzarlo
per eseguire le query di esempio, consulta
Configura ed esegui query su Spanner Graph.
Limita gli archi attraversati per migliorare le prestazioni delle query
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 con cardinalità elevata vengono 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 enormi 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 IS_FIRST
all'interno di una clausola FILTER per limitare il numero di archi attraversati dalla query da un nodo. Poiché gli account in FinGraph potrebbero avere un numero di transazioni
significativamente superiore rispetto ad altri, puoi utilizzare IS_FIRST per evitare una query
inefficiente. Questa tecnica è particolarmente utile quando non è necessaria un'enumerazione completa
di tutte le connessioni da un super nodo.
La seguente query trova gli account (a2) che ricevono trasferimenti direttamente o indirettamente da account bloccati (a1). La query utilizza IS_FIRST per evitare prestazioni lente quando un account ha molti trasferimenti limitando il numero di archi Transfers da considerare per ogni Account.
GRAPH FinGraph
MATCH
(a1:Account {is_blocked: true})
-[e:Transfers WHERE e IN
{
MATCH -[selected_e:Transfers]->
FILTER IS_FIRST(@max_transfers_per_account) OVER (
PARTITION BY SOURCE_NODE_ID(selected_e)
ORDER BY selected_e.create_time DESC)
RETURN selected_e
}
]->{1,5}
(a2:Account)
RETURN a1.id AS src_id, a2.id AS dst_id;
Questo esempio utilizza quanto segue:
@max_transfers_per_account: un parametro di query che specifica il numero massimo di archiTransfersda considerare per ogni account (a1).PARTITION BY SOURCE_NODE_ID(selected_e): garantisce che il limite diIS_FIRSTvenga applicato in modo indipendente per ogni account (a1).ORDER BY selected_e.create_time DESC: specifica che vengono restituiti i trasferimenti più recenti.
Esegui il campionamento dei nodi intermedi per ottimizzare le query multihop
Puoi anche migliorare l'efficienza delle query utilizzando IS_FIRST 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 multihop in più istruzioni MATCH separate da NEXT e applica IS_FIRST a metà percorso, dove devi campionare:
GRAPH FinGraph
MATCH (a1:Account {is_blocked: true})-[e1:Transfers]->(a2:Account)
FILTER IS_FIRST(1) OVER (PARTITION BY a2)
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;
Per capire come IS_FIRST ottimizza questa query:
La clausola
FILTER IS_FIRST(1) OVER (PARTITION BY a2)viene applicata nella prima istruzioneMATCH.Per ogni nodo dell'account intermedio (
a2),IS_FIRSTconsidera solo il primo arco in entrataTransfers(e1), riducendo il numero di percorsi da esplorare nella seconda istruzioneMATCH.L'efficienza complessiva della query a due hop viene migliorata perché il secondo
MATCHnon elabora dati non necessari, soprattutto quandoa2ha molti trasferimenti in entrata.
Passaggi successivi
- Scopri come eseguire query sui grafici delle proprietà in Spanner Graph.
- Esegui la migrazione a Spanner Graph.