Ottimizzare le prestazioni delle query GQL per il grafico in Microsoft Fabric

Questo articolo fornisce indicazioni per la scrittura di query GQL (Graph Query Language) che eseguono prestazioni prevedibili ed efficienti quando si lavora con il grafico in Microsoft Fabric. Le raccomandazioni sono basate sul comportamento corrente della piattaforma e sui vincoli documentati.

Per i limiti rigidi relativi alle dimensioni del grafo, alle dimensioni dei risultati e al timeout delle query, vedere Limitazioni correnti. Diversi consigli in questo articolo riguardano anche il modo in cui si progetta lo schema del grafo. Per altre informazioni, vedere Progettare uno schema del grafo.

Inserire filtri secondo la loro semantica

Posiziona un predicato all'interno di un pattern di grafo quando definisce quale nodo o arco può partecipare alla corrispondenza. Utilizzare una condizione a livello di istruzione MATCH ... WHERE per applicare un filtro successivo alla corrispondenza completa, oppure un'istruzione FILTER separata quando il predicato si applica alla riga prodotta da un'istruzione precedente.

Ad esempio, usare clausole a livello WHERE di pattern per le condizioni sui nodi abbinati:

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

Un elemento FILTER separato può esprimere la stessa condizione dopo una corrispondenza obbligatoria standard che utilizza la ricerca del percorso ALL predefinita:

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

L'ottimizzatore di query può applicare predicati equivalenti durante la scansione quando ciò preserva la semantica delle query, quindi la sintassi inline non è intrinsecamente più veloce. Scegli la forma che esprime quando la condizione si applica.

La posizione dei predicati può modificare i risultati con ANY SHORTEST. I predicati in linea limitano i percorsi idonei per la selezione del percorso più breve. Un WHERE a livello di istruzione o un successivo FILTER si applica dopo la selezione del cammino, quindi può rimuovere il cammino più breve selezionato senza selezionarne invece uno più lungo. Per la limitazione attuale MATCH ... WHERE e un modello di posizionamento affidabile, vedi Posizionare predicati prima o dopo la selezione del percorso.

Anche la posizione conta con OPTIONAL MATCH, in cui un WHERE in linea limita la corrispondenza facoltativa, ma un successivo FILTER può rimuovere la riga estesa con valori NULL.

Suggerimento

Pensa al livello di pattern WHERE lì come analogo a una condizione SQL JOIN ... ON. Descrive quali corrispondenze soddisfano i criteri, anziché filtrare successivamente la riga risultante.

Restituisce solo le proprietà necessarie

Restituisce solo le proprietà del nodo e dei bordi richiesti dallo scenario. Evitare di restituire nodi completi o usare RETURN * quando è necessario solo un subset di proprietà.

La selezione di proprietà non necessarie aumenta le dimensioni di lettura, serializzazione e risposta dei dati. Durante la modellazione dei grafi, seleziona solo le colonne sorgente di cui hai bisogno come proprietà del tipo di nodo.

Consigliato: Proiezione ridotta.

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

Evitare: Evitare di restituire nodi completi.

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

Annotazioni

Aggiungere proprietà del tipo di nodo solo durante la modellazione del grafo quando sono necessarie per le query o l'analisi. Un numero minore di proprietà per nodo riduce sia lo storage che l'overhead delle query.

Limitare le dimensioni del set di risultati

Applicare LIMIT o altre condizioni di limitazione al momento di eseguire query su nodi o relazioni con cardinalità elevata. Le corrispondenze del grafico illimitato possono produrre set di risultati molto grandi che si avvicinano ai limiti della piattaforma.

Consigliato: Risultati delimitati.

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

Evitare: Corrispondenza con cardinalità elevata non limitata.

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

Importante

Graph tronca le risposte alle query la cui rappresentazione binaria interna supera i 64 MB. Una risposta troncata contiene uno stato aggiuntivo con codice pubblico 01000 e GQLSTATUS canonico 01M11. Usa filtri, restringi le proiezioni e LIMIT riduce la dimensione del risultato. Per altre informazioni, vedere le limitazioni correnti.

Mantenere gli attraversamenti superficiali e mirati

Evitare modelli a grafo profondamente annidati o altamente complessi. Usare attraversamenti semplici e mirati che rispondono direttamente a una domanda specifica. Ogni hop aggiuntivo in un modello a lunghezza variabile può aumentare in modo esponenziale il numero di percorsi valutati dal motore, specialmente in grafici con connessione densa.

Consigliato: Vincoli stretti.

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

Evitare: Un intervallo di attraversamento troppo ampio senza una chiara necessità.

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

Importante

Il query builder visivo limita i percorsi di lunghezza variabile a otto hop, ma questo limite dell'interfaccia utente non si applica a GQL nell'editor di codice. Usa il limite più stretto che il tuo scenario permette perché un intervallo più ampio può corrispondere a più percorsi.

Usa TRAIL quando i sentieri non devono ripetere i bordi

Usa la modalità TRAIL path quando un percorso valido non deve ripetere alcun arco. Nei grafi con cicli, questa restrizione può anche ridurre il numero di percorsi di corrispondenza rispetto alla modalità predefinita WALK .

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

Senza TRAIL, la stessa query su un grafo ciclico può restituire percorsi che ripetono un arco. Usa la modalità che corrisponde alla semantica del percorso richiesta invece di trattarla TRAIL come un'ottimizzazione generale delle prestazioni.

Un pattern illimitato ALL WALK non è supportato perché i cicli possono produrre infiniti percorsi. Sebbene i pattern TRAIL, SIMPLE e ACYCLIC non associati terminino, possono comunque enumerare molti percorsi. Usa un limite superiore finito a meno che la query non richieda un attraversamento illimitato.

Usare variabili condivise per unioni efficienti

Quando una query richiede dati di più relazioni, usare una variabile condivisa per unire i modelli nella stessa entità. Senza una variabile condivisa, i modelli possono produrre un prodotto cartesiano, ogni combinazione di corrispondenze di entrambi i modelli, portando a un set di risultati molto più ampio.

Consigliato: La variabile p condivisa unisce i modelli.

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

Evitare: Modelli indipendenti senza variabile condivisa.

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

Un prodotto cartesiano associa ogni risultato da un modello con ogni risultato dall'altro. Se Person-workAt->Company corrisponde a 1.000 righe e Person-isLocatedIn->City corrisponde a 500 righe, la query restituisce 1.000 × 500 = 500.000 righe. L'aggiunta di una variabile condivisa vincola il join in modo che vengano restituite solo le coppie corrispondenti.

Filtra sulle proprietà chiave quando identifichi i nodi

Definire i vincoli delle chiavi dei nodi per identificare i nodi in modo univoco e garantire l'integrità dei dati. Quando hai bisogno di un nodo specifico, includi la sua proprietà chiave nel predicato del pattern per evitare di abbinare nodi non correlati.

Ad esempio, se il tipo di grafo definisce id come chiave per i Person nodi:

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

Poi filtra su id quando hai bisogno di quella persona:

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

Senza il filtro, la query trova tutti i nodi Person prima di attraversare gli archi workAt:

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

Suggerimento

Un vincolo chiave stabilisce identità e unicità. Non garantisce di per sé una particolare ricerca fisica o un determinato piano di esecuzione della query.

Scegliere i tipi di dati appropriati

Seleziona il tipo di dato che rappresenta i valori e le operazioni previste di ciascuna proprietà. Ad esempio, usa un tipo numerico per i valori che calcoli o confronti numericamente invece di memorizzare numeri formattati come stringhe.

Per i tipi di dati supportati, vedere Limitazioni correnti - Tipi di dati e Tipi di proprietà supportati.

Se possibile, recuperare le entità correlate in un singolo modello a grafo anziché eseguire query separate che attraversano gli stessi bordi in modo indipendente. La combinazione di attraversamenti evita gli abbinamenti di pattern ridondanti e impedisce il problema N+1 delle query, in cui una query iniziale attiva una query separata per ogni riga di risultato.

Consigliato: Modello combinato singolo.

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

Evitare: Due query separate che attraversano lo stesso Customer → Order arco.

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

Testare query con volumi di dati realistici

Le query che funzionano correttamente su set di dati di piccole dimensioni potrebbero non essere ridimensionate in modo lineare. Testare le query con volumi di dati che rappresentano il carico di lavoro di produzione previsto.

  • Preferisce forme di query conservatrici che includono filtri e limiti.
  • Evitare interrogazioni esplorative che restituiscono tutto su grafici di grandi dimensioni.
  • Monitorare la durata della query rispetto al limite di timeout di 20 minuti.