Questo documento descrive come eseguire query sui grafici delle proprietà in Spanner Graph. La di alcuni esempi di questa sezione utilizzano lo schema del grafico che crei Configura ed esegui query sul grafico Spanner, che viene illustrato nel seguente diagramma:
Esegui una query sul grafico di Spanner
Puoi eseguire query su Spanner Graph nei seguenti modi:
Nella console Google Cloud
Invia una query nella pagina di Spanner Studio. Per accedere alla pagina Spanner Studio, fai clic su Spanner Studio nella pagina Panoramica del database o Panoramica della tabella. Per ulteriori informazioni su come accedere a Spanner Studio, consulta Gestire i dati utilizzando la console Google Cloud.
Lo strumento a riga di comando
gcloud spanner
Invia un comando utilizzando il comando
gcloud spanner databases execute-sql
.La
executeSql
e API RESTexecuteStreamingSql
Le API RPC
ExecuteSql
eExecuteStreamingSql
Struttura delle query del grafico Spanner
Questa sezione descrive in dettaglio ogni componente della query.
L'esempio seguente illustra la struttura di base di un grafico Spanner query.
Spanner Graph consente di creare più grafici all'interno di un database.
La query inizia specificando il grafico di destinazione, FinGraph
, utilizzando
la clausola GRAPH
.
Corrispondenza pattern del grafico
La corrispondenza di pattern del grafico trova pattern specifici all'interno del grafico. I pattern più di base sono i pattern di elementi (pattern di nodi e pattern di bordi), che corrispondono agli elementi del grafico (rispettivamente nodi e bordi). I pattern degli elementi possono essere composti pattern dei percorsi e di pattern più complessi.
Pattern di nodo
Un pattern di nodi è un pattern che corrisponde ai nodi del grafico. Questo pattern comprende una coppia di parentesi che possono essere abbinate, che può optionally contiene una variabile di pattern grafico, un'espressione di etichetta e filtri delle proprietà.
Trova tutti i nodi
La seguente query restituisce tutti i nodi del grafo. La variabile n
, chiamata
variabile pattern grafico, si lega ai nodi corrispondenti. In questo caso, il pattern
del nodo corrisponde a tutti i nodi del grafico.
GRAPH FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;
Risultato
La query restituisce label
e id
come segue:
etichetta | ID |
---|---|
Account | 7 |
Account | 16 |
Account | 20 |
Persona | 1 |
Persona | 2 |
Persona | 3 |
Trovare tutti i nodi con un'etichetta specifica
La seguente query corrisponde a tutti i nodi nel grafico con Person
etichetta.
La query restituisce le proprietà label
, id
e name
dei nodi corrispondenti.
GRAPH FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;
Risultato
etichetta | ID | nome |
---|---|---|
Persona | 1 | Alessandro |
Persona | 2 | Dana |
Persona | 3 | Lee |
Trovare tutti i nodi corrispondenti a un'espressione di etichetta
Puoi creare un'espressione di etichetta con uno o più operatori logici.
La seguente query corrisponde a tutti i nodi del grafo che hanno l'etichetta Person
o Account
. L'insieme di proprietà esposte dalla variabile del pattern grafico n
è il superinsieme delle proprietà esposte dai nodi con l'etichetta Person
o Account
.
GRAPH FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;
- Nei risultati, tutti i nodi hanno la proprietà
id
. - I nodi corrispondenti all'etichetta
Account
hanno la proprietàcreate_time
, ma non la proprietàbirthday
. Viene restituito un valoreNULL
per la proprietàbirthday
per questi nodi. - I nodi corrispondenti all'etichetta
Person
hanno la proprietàbirthday
, ma non la proprietàcreate_time
. Per la proprietàcreate_time
viene restituito un valoreNULL
per questi nodi.
Risultato
etichetta | ID | compleanno | create_time |
---|---|---|---|
Account | 7 | NULL | 2020-01-10T14:22:20.222Z |
Account | 16 | NULL | 2020-01-28T01:55:09.206Z |
Account | 20 | NULL | 2020-02-18T13:44:20.655Z |
Persona | 1 | 1991-12-21T08:00:00Z | NULL |
Persona | 2 | 1980-10-31T08:00:00Z | NULL |
Persona | 3 | 1986-12-07T08:00:00Z | NULL |
Per saperne di più sulle regole delle espressioni delle etichette, consulta Espressione dell'etichetta.
Trova tutti i nodi corrispondenti all'espressione di etichetta e al filtro delle proprietà
La seguente query abbina tutti i nodi del grafo che hanno l'etichetta Person
e la cui proprietà id
è uguale a 1
.
GRAPH FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;
Risultato
etichetta | ID | nome | compleanno |
---|---|---|---|
Persona | 1 | Alessandro | 1991-12-21T08:00:00Z |
Puoi utilizzare la clausola WHERE
per formare condizioni di filtro più complesse su
etichette e proprietà.
La seguente query corrisponde a tutti i nodi del grafo che hanno l'etichetta Person
e la proprietà birthday
è precedente a 1990-01-10
.
GRAPH FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;
Risultato
etichetta | nome | compleanno |
---|---|---|
Persona | Dana | 1980-10-31T08:00:00Z |
Persona | Lee | 1986-12-07T08:00:00Z |
Motivi bordi
Un pattern perimetrale associa gli angoli o le relazioni tra i nodi. I pattern dei bordi sono
racchiuse tra parentesi quadre []
con i simboli -
, ->
o <-
per indicare
indicazioni stradali.
Analogamente ai pattern dei nodi, le variabili di pattern del grafico vengono utilizzate per l'associazione al bordo corrispondente elementi.
Trova tutti gli spigoli con etichette corrispondenti
La seguente query restituisce tutti gli archi del grafo che hanno l'etichetta Owns
.
La variabile del pattern del grafico e
è associata ai bordi corrispondenti.
GRAPH FinGraph
MATCH -[e:Owns]->
RETURN e.id AS owner_id, e.account_id;
Risultato
owner_id | account_id |
---|---|
1 | 7 |
3 | 16 |
2 | 20 |
Trova tutti gli spigoli corrispondenti all'espressione dell'etichetta e al filtro della proprietà
Analogamente a un pattern di nodi, un pattern di edge può utilizzare espressioni di etichetta, specifica delle proprietà e clausole WHERE
, come mostrato nella query seguente. La query trova tutti gli spigoli etichettati con Owns
e con la proprietà create_time
in un periodo specificato.
GRAPH FinGraph
MATCH -[e:Owns WHERE e.create_time > '2020-01-14'
AND e.create_time < '2020-05-14']->
RETURN e.id AS owner_id, e.create_time, e.account_id;
Risultato
owner_id | create_time | account_id |
---|---|---|
2 | 2020-01-28T01:55:09.206Z | 20 |
3 | 2020-02-18T13:44:20.655Z | 16 |
Trova tutti i bordi utilizzando qualsiasi pattern dei bordi di direzione
Sebbene tutti i bordi del grafico Spanner siano diretti, puoi utilizzare il metodo
any direction
pattern del bordo -[]-
in una query per creare corrispondenze con i bordi in entrambe le direzioni.
La seguente query trova tutti i trasferimenti in cui è coinvolto un account bloccato.
GRAPH FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account)
WHERE account.is_blocked
RETURN transfer.order_number, transfer.amount;
Risultato
order_number | quantità |
---|---|
304330008004315 | 300 |
304120005529714 | 100 |
103650009791820 | 300 |
302290001255747 | 200 |
Pattern di percorso
Un pattern di percorso viene creato a partire dall'alternanza di pattern di nodi e margini.
Trovare tutti i percorsi da un nodo con filtri di etichette e proprietà specificati utilizzando un pattern di percorso
La seguente query trova tutti i trasferimenti a un account avviati da un account di proprietà di Person
con id
uguale a 2
.
Ogni risultato corrispondente rappresenta un percorso da Person
{id: 2}
a un
connesso Account
tramite il perimetro Owns
, a un altro Account
tramite
Transfers
.
GRAPH FinGraph
MATCH
(p:Person {id: 2})-[:Owns]->(account:Account)-[t:Transfers]->
(to_account:Account)
RETURN
p.id AS sender_id, account.id AS from_id, to_account.id AS to_id;
Risultato
sender_id | from_id | to_id |
---|---|---|
2 | 20 | 7 |
2 | 20 | 16 |
Pattern di percorsi quantificati
Un pattern quantificato consente di ripetere un pattern all'interno di un intervallo specificato.
Abbina un pattern dei bordi quantificato
La seguente query trova tutti gli account di destinazione a uno a tre trasferimenti da un account di origine Account
con id
uguale a 7
, diverso da sé stesso.
Il pattern del bordo è stato corretto con il quantificatore {1, 3}
.
GRAPH FinGraph
MATCH (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account)
WHERE src != dst
RETURN src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length, dst.id AS dst_account_id;
Risultato
src_account_id | path_length | dst_account_id |
---|---|---|
7 | 1 | 16 |
7 | 1 | 16 |
7 | 1 | 16 |
7 | 3 | 16 |
7 | 3 | 16 |
7 | 2 | 20 |
7 | 2 | 20 |
L'esempio precedente utilizza la funzione ARRAY_LENGTH
per accedere al
group variable
e
. Per maggiori informazioni, consulta la variabile del gruppo di accesso.
Alcune righe dei risultati di esempio sono ripetute perché potrebbero esserci più righe
percorsi tra la stessa coppia di account src
e dst
che corrispondono al pattern.
Abbina un pattern di percorso quantificato
La seguente query trova i percorsi tra i nodi Account
con uno o due bordi Transfers
tramite account intermedi bloccati.
Il pattern del percorso tra parentesi è quantificato e la clausola WHERE
viene utilizzata tra le parentesi per specificare le condizioni per il pattern ripetuto.
GRAPH FinGraph
MATCH
(src:Account)
((:Account)-[:Transfers]->(interm:Account) WHERE interm.is_blocked){1,2}
-[:Transfers]->(dst:Account)
RETURN src.id AS src_account_id, dst.id AS dst_account_id;
Risultato
src_account_id | dst_account_id |
---|---|
7 | 20 |
7 | 20 |
20 | 20 |
Variabili di gruppo
Una variabile con pattern del grafico dichiarata secondo un pattern quantificato è considerata una variabile di gruppo se vi si accede al di fuori del pattern quantificato e si lega a un array di che corrispondono a elementi del grafico.
Puoi accedere a una variabile di gruppo come array in cui gli elementi del grafico vengono conservati nell'ordine in cui appaiono lungo i percorsi corrispondenti. Puoi aggregare un gruppo utilizzando l'aggregazione orizzontale.
Variabile gruppo di accesso
Nel seguente esempio, si accede alla variabile e
come segue:
- Una variabile di pattern del grafico associata a un singolo bordo nella clausola
WHERE
e.amount > 100
(entro il pattern quantificato). - Una variabile di gruppo associata a un array di elementi periferici in
ARRAY_LENGTH(e)
nell'istruzioneRETURN
(al di fuori del pattern quantificato). - Una variabile di gruppo associata a un array di elementi di bordo, aggregata da
SUM(e.amount)
al di fuori del pattern quantificato. Ecco un esempio aggregazione orizzontale.
GRAPH FinGraph
MATCH
(src:Account {id: 7})-[e:Transfers WHERE e.amount > 100]->{0,2}
(dst:Account)
WHERE src.id != dst.id
LET total_amount = SUM(e.amount)
RETURN
src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length,
total_amount, dst.id AS dst_account_id;
Risultato
src_account_id | path_length | total_amount | dst_account_id |
---|---|---|---|
7 | 1 | 300 | 16 |
7 | 2 | 600 | 20 |
Percorsi qualsiasi e Percorsi più brevi
Per limitare i percorsi corrispondenti in ogni gruppo di percorsi che condividono gli stessi nodi di origine e di destinazione, puoi utilizzare il prefisso di ricerca del percorso ANY
o ANY SHORTEST
.
Puoi applicare questi prefissi solo prima di un intero pattern del percorso,
e non puoi applicarle tra parentesi.
Corrispondenza utilizzando QUALSIASI
La seguente query trova tutti gli account univoci raggiungibili che sono uno o due
Transfers
di distanza da un determinato nodo Account
.
Il prefisso di ricerca del percorso ANY
garantisce che un solo percorso tra un indirizzo
viene restituita la coppia di nodi src
e dst
Account
. Nell'esempio seguente, anche se puoi raggiungere il nodo Account
con {id: 16}
in due percorsi diversi dal nodo Account
di origine, i risultati includono un solo percorso.
GRAPH FinGraph
MATCH ANY (src:Account {id: 7})-[e:Transfers]->{1,2}(dst:Account)
LET ids_in_path = ARRAY(SELECT e.to_id FROM UNNEST(e) AS e)
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ids_in_path;
Risultato
src_account_id | dst_account_id | ids_in_path |
---|---|---|
7 | 16 | 16 |
7 | 20 | 16,20 |
Tracciare i pattern del grafico
Un pattern del grafico è costituito da uno o più pattern di percorso, separati da una virgola ,
.
I pattern del grafico possono contenere una clausola WHERE
che consente di accedere a tutti i
variabili di pattern del grafico nei pattern del percorso per formare condizioni di filtro. Ogni pattern
di percorso produce una raccolta di percorsi.
Corrispondenza utilizzando un pattern grafico
La seguente query identifica gli account intermediari e i relativi proprietari coinvolti di transazioni per importi superiori a 200, attraverso le quali vengono trasferiti fondi da un account di origine a un account bloccato.
I seguenti pattern di percorso formano il pattern del grafico:
- Il primo pattern trova i percorsi in cui il trasferimento avviene da una a un account bloccato utilizzando un account intermedio.
- Il secondo pattern trova i percorsi da un account al rispettivo proprietario.
La variabile interm
funge da collegamento comune tra i due pattern di percorso, il che richiede che interm
faccia riferimento allo stesso nodo elemento in entrambi i pattern di percorso. Questo
crea un'operazione equi-join basata sulla variabile interm
.
GRAPH FinGraph
MATCH
(src:Account)-[t1:Transfers]->(interm:Account)-[t2:Transfers]->(dst:Account),
(interm)<-[:Owns]-(p:Person)
WHERE dst.is_blocked = TRUE AND t1.amount > 200 AND t2.amount > 200
RETURN
src.id AS src_account_id, dst.id AS dst_account_id,
interm.id AS interm_account_id, p.id AS owner_id;
Risultato
src_account_id | dst_account_id | interm_account_id | owner_id |
---|---|---|---|
20 | 16 | 7 | 1 |
Istruzioni di query lineari
Puoi concatenare più istruzioni del grafico per formare un'istruzione di query lineare. Le istruzioni vengono eseguite nello stesso ordine in cui appaiono nella query.
- Ogni istruzione prende come input l'output dell'istruzione precedente. La l'input è vuoto per la prima istruzione.
- L'output dell'ultima istruzione è il risultato finale.
Trovare il numero massimo di trasferimenti a un account bloccato
La seguente query trova l'account e il relativo proprietario con il trasferimento in uscita più elevato a un account bloccato.
GRAPH FinGraph
MATCH (src_account:Account)-[transfer:Transfers]->(dst_account:Account)
WHERE dst_account.is_blocked
ORDER BY transfer.amount DESC
LIMIT 1
MATCH (src_account:Account)<-[owns:Owns]-(owner:Person)
RETURN src_account.id AS account_id, owner.name AS owner_name;
La tabella seguente illustra come vengono trasmessi i risultati intermedi le dichiarazioni. Per brevità, vengono mostrate solo alcune proprietà dei risultati intermedi.
Affermazione | Risultato intermedio (abbreviato) | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MATCH (src_account:Account) -[transfer:Transfers]-> (dst_account:Account) WHERE dst_account.is_blocked |
|
||||||||||||
ORDER BY transfer.amount DESC |
|
||||||||||||
LIMIT 1 |
|
||||||||||||
MATCH (src_account:Account) <-[owns:Owns]- (owner:Person) |
|
||||||||||||
RETURN src_account.id AS account_id, owner.name AS owner_name |
|
Risultato
account_id | owner_name |
---|---|
7 | Alex |
Estratto conto della restituzione
L'istruzione Return definisce cosa restituire dai pattern corrispondenti. Può accedere alle variabili dei pattern di grafici, contenere espressioni e altre clausole come ORDER_BY,
GROUP_BY. Consulta la dichiarazione RETURN
.
Tieni presente che Spanner Graph non supporta la restituzione di elementi del grafico come risultati
delle query. Per restituire l'intero elemento del grafico, utilizza la funzione TO_JSON
.
Restituisci gli elementi del grafico in formato JSON
GRAPH FinGraph
MATCH (n:Account {id: 7})
-- Returning a graph element in the final results is NOT allowed. Instead, use
-- the TO_JSON function or explicitly return the graph element's properties.
RETURN TO_JSON(n) AS n;
Risultato
n |
---|
{"identifier":"mUZpbkdyYXBoLkFjY291bnQAeJEO","kind":"node","labels":["Account"],"properties":{"create_time":"2020-01-10T14:22:20.222Z","id":7,"is_blocked":false,"nick_name":"Vacation Fondo"}} |
Creazione di query più grandi con la parola chiave AVANTI
Puoi concatenare più istruzioni di query lineari del grafico utilizzando la parola chiave NEXT
. L'input per la prima istruzione di query lineare è vuoto. L'output di ogni
l'istruzione di query lineare diventa l'input della successiva istruzione di query lineare.
L'esempio seguente trova il proprietario dell'account con il numero di entrate
i trasferimenti concatenando più istruzioni lineari di un grafico. Tieni presente che
puoi utilizzare la stessa variabile, account
in questo esempio, per fare riferimento allo stesso grafico
su più istruzioni lineari.
GRAPH FinGraph
MATCH (:Account)-[:Transfers]->(account:Account)
RETURN account, COUNT(*) AS num_incoming_transfers
GROUP BY account
ORDER BY num_incoming_transfers DESC
LIMIT 1
NEXT
MATCH (account:Account)<-[:Owns]-(owner:Person)
RETURN account.id AS account_id, owner.name AS owner_name, num_incoming_transfers;
Risultato
account_id | owner_name | num_incoming_transfers |
---|---|---|
16 | Lee | 3 |
Funzioni ed espressioni
Puoi usare tutte le funzioni, gli operatori e le condizionali in GoogleSQL, incluse le funzioni aggregate e altre funzioni scalari nella query del grafico di Spanner.
Spanner Graph supporta anche funzioni e operatori integrati per gli elementi del grafico.
Funzioni e operatori integrati
Le seguenti funzioni e operatori vengono comunemente utilizzati in GQL:
PROPERTY_EXISTS(n, birthday)
: restituisce sen
esponebirthday
proprietà.LABELS(n)
: restituisce le etichette din
come definito nello schema del grafico.PROPERTY_NAMES(n)
: restituisce i nomi delle proprietà din
.TO_JSON(n)
: restituiscen
in formato JSON. Per ulteriori informazioni, consulta FunzioneTO_JSON
.
La seguente query illustra il predicato PROPERTY_EXISTS
, la funzioneLABELS
e la funzione
TO_JSON
, nonché altre funzioni integrate come ARRAY_AGG
e
CONCAT
.
GRAPH FinGraph
MATCH (person:Person)-[:Owns]->(account:Account)
RETURN person, ARRAY_AGG(account.nick_name) AS accounts
GROUP BY person
NEXT
RETURN
LABELS(person) AS labels,
TO_JSON(person) AS person,
accounts,
CONCAT(person.city, ", ", person.country) AS location,
PROPERTY_EXISTS(person, is_blocked) AS is_blocked_property_exists,
PROPERTY_EXISTS(person, name) AS name_property_exists
LIMIT 1;
Risultato
is_blocked_property_exists | name_property_exists | etichette | account | località | persona |
---|---|---|---|---|---|
falso | true | Persona | ["Vacation Fund"] | Adelaide, Australia | {"identifier":"mUZpbkdyYXBoLlBlcnNvbgB4kQI=","kind":"node","labels":["Person"],"properties":{"birthday":"1991-12-21T08:00:00Z","city":"Adelaide","country":"Australia","id":1,"name":"Alex"}} |
Sottoquery
Una sottoquery è una query nidificata in un'altra query. Di seguito sono elencate le regole per le sottoquery di Spanner Graph:
- Una sottoquery è racchiusa tra una coppia di parentesi graffe
{}
. - Una sottoquery potrebbe iniziare con la clausola
GRAPH
iniziale per specificare grafico nell'ambito. Il grafico specificato non deve necessariamente essere uguale al grafico usata nella query esterna. - Quando la clausola
GRAPH
viene omessa nella sottoquery, si verifica quanto segue:- Il grafico nell'ambito viene dedotto dal contesto di query esterno più vicino.
- La sottoquery deve iniziare da un'istruzione di corrispondenza di pattern del grafico
con
MATCH.
- Una variabile con pattern del grafico dichiarata fuori dall'ambito della sottoquery non può essere dichiarate di nuovo all'interno della sottoquery, ma può essere fatto riferimento in espressioni o funzioni all'interno della sottoquery.
Utilizzare una sottoquery per trovare il numero totale di trasferimenti da ciascun account
La seguente query illustra l'utilizzo della sottoquery VALUE
. La sottoquery è chiusa tra parentesi graffe {}
con prefisso della parola chiave VALUE
. La query restituisce l'importo totale
di trasferimenti avviati da un account.
GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(account:Account)
RETURN p.name, account.id AS account_id, VALUE {
MATCH (a:Account)-[transfer:Transfers]->(:Account)
WHERE a = account
RETURN SUM(transfer.amount) AS total_transfer
} AS total_transfer;
Risultato
nome | account_id | total_transfer |
---|---|---|
Alessandro | 7 | 400 |
Dana | 20 | 700 |
Lee | 16 | 300 |
Per un elenco delle espressioni di sottoquery supportate, consulta Sottoquery di Spanner.
Parametri di query
Puoi eseguire query su Spanner Graph con parametri. Per ulteriori informazioni, consulta sintassi e scopri come dati delle query con parametri nelle librerie client di Spanner.
La seguente query illustra l'utilizzo dei parametri di query.
GRAPH FinGraph
MATCH (person:Person {id: @id})
RETURN person.name;
Esegui query su grafici e tabelle contemporaneamente
Puoi utilizzare le query sui grafici in combinazione con SQL per accedere alle informazioni dei tuoi grafici e delle tue tabelle in un'unica istruzione.
GRAPH_TABLE
L'operatore GRAPH_TABLE
prende una query sul grafico lineare e restituisce il risultato in un formato tabulare che può essere integrato perfettamente in una query SQL. Questa interoperabilità ti consente di arricchire i risultati delle query sui grafici con contenuti non grafici e viceversa.
Ad esempio, puoi creare una tabella CreditReports
e inserire alcuni crediti
come mostrato nell'esempio seguente:
CREATE TABLE CreditReports (
person_id INT64 NOT NULL,
create_time TIMESTAMP NOT NULL,
score INT64 NOT NULL,
) PRIMARY KEY (person_id, create_time);
INSERT INTO CreditReports (person_id, create_time, score)
VALUES
(1,"2020-01-10 06:22:20.222", 700),
(2,"2020-02-10 06:22:20.222", 800),
(3,"2020-03-10 06:22:20.222", 750);
Poi, identifica le persone interessanti tramite la corrispondenza di pattern del grafico in GRAPH_TABLE
e unisci i risultati della query del grafico con la tabella CreditReports
per accedere al merito
punteggio.
SELECT
gt.person.id,
credit.score AS latest_credit_score
FROM GRAPH_TABLE(
FinGraph
MATCH (person:Person)-[:Owns]->(:Account)-[:Transfers]->(account:Account)
WHERE account.is_blocked
RETURN DISTINCT person
) AS gt
JOIN CreditReports AS credit
ON gt.person.id = credit.person_id
ORDER BY credit.create_time;
Risultato:
person_id | latest_credit_score |
---|---|
1 | 700 |
2 | 800 |
Passaggi successivi
Scopri le best practice per l'ottimizzazione delle query.