Best practice di SQL

Come descritto in Piani di esecuzione delle query, il compilatore SQL trasforma un'istruzione SQL in un piano di esecuzione di query, utilizzati per ottenere i risultati della query. In questa pagina vengono descritte le best practice relative a creando istruzioni SQL per aiutare Spanner a trovare un'esecuzione efficiente piani.

Le istruzioni SQL di esempio mostrate in questa pagina utilizzano il seguente schema di esempio:

GoogleSQL

CREATE TABLE Singers (
 SingerId   INT64 NOT NULL,
 FirstName  STRING(1024),
 LastName   STRING(1024),
 SingerInfo BYTES(MAX),
 BirthDate  DATE
) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
 SingerId     INT64 NOT NULL,
 AlbumId      INT64 NOT NULL,
 AlbumTitle   STRING(MAX),
 ReleaseDate  DATE
) PRIMARY KEY (SingerId, AlbumId),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

Per il riferimento SQL completo, consulta Sintassi delle dichiarazioni Funzioni e operatori, e sintassi e struttura legislativa.

PostgreSQL

CREATE TABLE Singers (
 SingerId   BIGINT PRIMARY KEY,
 FirstName  VARCHAR(1024),
 LastName   VARCHAR(1024),
 SingerInfo BYTEA,
 BirthDate  TIMESTAMPTZ
);

CREATE TABLE Albums (
 SingerId        BIGINT NOT NULL,
 AlbumId         BIGINT NOT NULL,
 AlbumTitle      VARCHAR(1024),
 ReleaseDate     DATE,
 PRIMARY KEY(SingerId, AlbumId),
 FOREIGN KEY (SingerId) REFERENCES Singers(SingerId)
) INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

Per ulteriori informazioni, consulta Il linguaggio PostgreSQL in Spanner.

Utilizzare parametri di ricerca

Spanner supporta parametri di ricerca per aumentare le prestazioni e aiutare Impedire SQL injection quando le query vengono create utilizzando input utente. Puoi utilizzare parametri di ricerca come sostituti di espressioni arbitrarie, ma non come sostituisce identificatori, nomi di colonna, nomi di tabella o altre parti del query.

I parametri possono apparire ovunque sia previsto un valore letterale. Uguale parametro può essere utilizzato più di una volta in una singola istruzione SQL.

Per riassumere, parametri di ricerca supportano l'esecuzione delle query nei seguenti modi:

  • Piani preottimizzati: le query che utilizzano parametri possono essere eseguite più velocemente su a ogni chiamata, perché la parametrizzazione semplifica Spanner per memorizzare nella cache il piano di esecuzione.
  • Composizione semplificata delle query: non è necessario eseguire l'escape dei valori stringa quando fornendole nei parametri di ricerca. I parametri di ricerca riducono inoltre il rischio errori di sintassi.
  • Sicurezza: i parametri di query rendono le tue query più sicure proteggendoti da vari attacchi di SQL injection. Questa protezione è particolarmente importante per le query create a partire dall'input utente.

Scopri come Spanner esegue le query

Spanner consente di eseguire query sui database utilizzando istruzioni SQL dichiarative che specificano i dati da recuperare. Se vuoi capire Spanner ottiene i risultati ed esamina il piano di esecuzione per la query. R il piano di esecuzione della query visualizza il costo di calcolo associato a ogni passaggio della query. Utilizzando questi costi, puoi eseguire il debug dei problemi di prestazioni delle query ottimizzare la query. Per saperne di più, consulta Piani di esecuzione delle query.

Puoi recuperare i piani di esecuzione delle query tramite la console Google Cloud oppure le librerie client.

Per ottenere un piano di esecuzione per una query specifica utilizzando la console Google Cloud, segui questi passaggi:

  1. Apri la pagina Istanze Spanner.

    Vai alle istanze Spanner

  2. Seleziona i nomi dell'istanza Spanner e il database che su cui vuoi eseguire una query.

  3. Fai clic su Spanner Studio nel pannello di navigazione a sinistra.

  4. Digita la query nel campo di testo, quindi fai clic su Esegui query.

  5. Fai clic su Spiegazione
    . La console Google Cloud mostra di esecuzione del piano di controllo per la tua query.

    Screenshot del piano di esecuzione visiva nella console Cloud

Per maggiori informazioni su come comprendere i piani visivi e utilizzarli per il debug vedi Ottimizzare una query utilizzando il visualizzatore del piano di query.

Puoi anche visualizzare esempi di piani di query storici e confrontare le prestazioni di una query nel tempo per determinate query. Per saperne di più, vedi Piani di query campionati.

Utilizza indici secondari

Come altri database relazionali, Spanner offre indici secondari, per il recupero dei dati mediante un'istruzione SQL l'interfaccia di lettura di Spanner. Il modo più comune per recuperare i dati da un è l'uso di Spanner Studio. Utilizzo di un indice secondario in una query SQL consente di specificare come vuoi che Spanner ottenga i risultati. La specifica di un indice secondario può velocizzare l'esecuzione delle query.

Ad esempio, supponi di voler recuperare gli ID di tutti i cantanti con un un cognome specifico. Un modo per scrivere una query SQL di questo tipo è:

SELECT s.SingerId
FROM Singers AS s
WHERE s.LastName = 'Smith';

Questa query restituirà i risultati previsti, ma potrebbe richiedere un molto tempo per restituire i risultati. La tempistica dipende dal numero di righe nella tabella Singers e quanti soddisfano il predicato WHERE s.LastName = 'Smith'. Se non esiste un indice secondario contiene la colonna LastName da cui leggere, il piano di query leggerebbe l'intera tabella Singers per trovare le righe che corrispondono al predicato. Lettura di tutti i dati tabella è chiamata scansione completa della tabella. La scansione completa della tabella è un'attività per ottenere risultati quando la tabella contiene solo una piccola percentuale di Singers con questo cognome.

Puoi migliorare le prestazioni di questa query definendo un indice secondario su la colonna del cognome:

CREATE INDEX SingersByLastName ON Singers (LastName);

Poiché l'indice secondario SingersByLastName contiene la tabella indicizzata colonna LastName e la colonna di chiave primaria SingerId, Spanner può recuperare tutti i dati dalla tabella indice molto più piccola anziché analizzare tabella Singers completa.

In questo scenario, Spanner utilizza automaticamente indicizzare SingersByLastName durante l'esecuzione della query (purché tre giorni siano passato dalla creazione del database; vedi Una nota sui nuovi database). Tuttavia, è meglio indicare esplicitamente a Spanner di usare quell'indice specificando un'istruzione di indice nella clausola FROM:

GoogleSQL

SELECT s.SingerId
FROM Singers@{FORCE_INDEX=SingersByLastName} AS s
WHERE s.LastName = 'Smith';

PostgreSQL

 SELECT s.SingerId
FROM Singers /*@ FORCE_INDEX=SingersByLastName */ AS s
WHERE s.LastName = 'Smith';

Ora supponi di voler recuperare anche il nome del cantante, oltre al ID. Anche se la colonna FirstName non è contenuta nell'indice, devi specificare comunque la direttiva "index" come prima:

GoogleSQL

SELECT s.SingerId, s.FirstName
FROM Singers@{FORCE_INDEX=SingersByLastName} AS s
WHERE s.LastName = 'Smith';

PostgreSQL

SELECT s.SingerId, s.FirstName
FROM Singers /*@ FORCE_INDEX=SingersByLastName */ AS s
WHERE s.LastName = 'Smith';

Puoi comunque ottenere un vantaggio in termini di prestazioni dall'uso dell'indice perché Spanner non deve eseguire una scansione completa della tabella durante l'esecuzione del piano di query. Invece, seleziona il sottoinsieme di righe che soddisfa il predicato da SingersByLastName indice ed esegue una ricerca nella tabella di base Singers per recuperare il primo solo per quel sottoinsieme di righe.

Se vuoi che Spanner non debba recuperare nessuna riga dalla base tabella, puoi archiviare una copia della colonna FirstName nella indicizzabile:

GoogleSQL

CREATE INDEX SingersByLastName ON Singers (LastName) STORING (FirstName);

PostgreSQL

CREATE INDEX SingersByLastName ON Singers (LastName) INCLUDE (FirstName);

Utilizzo di una clausola STORING (per il dialetto GoogleSQL) o di una clausola INCLUDE (per il dialetto PostgreSQL) come questo costa spazio di archiviazione aggiuntivo, offre i seguenti vantaggi:

  • Query SQL che utilizzano l'indice e selezionano le colonne archiviate in STORING o La clausola INCLUDE non richiede un join aggiuntivo alla tabella di base.
  • Le chiamate di lettura che utilizzano l'indice possono leggere le colonne archiviate in STORING o Clausola INCLUDE.

Gli esempi precedenti illustrano come gli indici secondari possano velocizzare le query quando le righe scelte dalla clausola WHERE di una query possono essere identificate rapidamente utilizzando l'indice secondario.

Un altro scenario in cui gli indici secondari possono offrire i vantaggi in termini di prestazioni sono per determinate query che restituiscono risultati ordinati. Per Ad esempio, supponi di voler recuperare tutti i titoli degli album e le relative date di uscita. in ordine crescente per la data di rilascio e in ordine decrescente per il titolo dell'album. Potresti scrivere una query SQL come segue:

SELECT a.AlbumTitle, a.ReleaseDate
FROM Albums AS a
ORDER BY a.ReleaseDate, a.AlbumTitle DESC;

Senza un indice secondario, questa query richiede un ordinamento potenzialmente costoso passaggio nel piano di esecuzione. Puoi velocizzare l'esecuzione della query definendo questo indice secondario:

CREATE INDEX AlbumsByReleaseDateTitleDesc on Albums (ReleaseDate, AlbumTitle DESC);

Quindi, riscrivi la query per utilizzare l'indice secondario:

GoogleSQL

SELECT a.AlbumTitle, a.ReleaseDate
FROM Albums@{FORCE_INDEX=AlbumsByReleaseDateTitleDesc} AS a
ORDER BY a.ReleaseDate, a.AlbumTitle DESC;

PostgreSQL

SELECT a.AlbumTitle, a.ReleaseDate
FROM Albums /*@ FORCE_INDEX=AlbumsByReleaseDateTitleDesc */ AS s
ORDER BY a.ReleaseDate, a.AlbumTitle DESC;

Questa definizione di query e indice soddisfano entrambi i seguenti criteri:

  • Per rimuovere il passaggio di ordinamento, assicurati che l'elenco delle colonne nell'ORDER BY è un prefisso dell'elenco delle chiavi di indice.
  • Per evitare di unire i dati dalla tabella di base al recupero delle colonne mancanti, assicurati che l'indice copra tutte le colonne della tabella utilizzate dalla query.

Sebbene gli indici secondari possano velocizzare le query comuni, l'aggiunta indici secondari possono aggiungere latenza alle operazioni di commit, poiché di solito richiede l'inserimento di un nodo aggiuntivo in ogni commit. Per per la maggior parte dei carichi di lavoro, avere alcuni indici secondari va bene. Tuttavia, devi valuta se ti interessa di più la latenza di lettura o scrittura e valuta operazioni sono fondamentali per il carico di lavoro. Esegui il benchmarking per assicurarti che le prestazioni siano quelle previste.

Per il riferimento completo sugli indici secondari, consulta in Indici secondari.

Ottimizza le scansioni

Per alcune query Spanner potrebbero essere utili durante la scansione dei dati, piuttosto che il più comune metodo di orientamento di elaborazione dei dati. L'elaborazione delle scansioni in batch è un modo più efficiente elaborare grandi volumi di dati contemporaneamente e consentire alle query di raggiungere di utilizzo e latenza della CPU ridotti.

L'operazione di scansione di Spanner avvia sempre l'esecuzione in modalità orientata alle righe. Durante questo periodo, Spanner raccoglie diversi metriche di runtime. Spanner applica quindi un insieme di euristiche basate sul risultato di queste metriche per determinare la modalità di scansione ottimale. Quando appropriata, Spanner passa a una modalità di elaborazione orientata al batch per migliorare la velocità effettiva e le prestazioni della scansione.

Casi d'uso comuni

Le query con le seguenti caratteristiche in genere traggono vantaggio dall'uso di elaborazione orientata al batch:

  • Scansioni di grandi dimensioni su dati aggiornati raramente.
  • Scansioni con predicati su colonne a larghezza fissa.
  • Scansioni con conteggi lunghi. (una ricerca utilizza un indice per recuperare i record).

Casi d'uso senza miglioramenti delle prestazioni

Non tutte le query traggono vantaggio dall'elaborazione orientata al batch. La seguente query tipi funzionano meglio con l'elaborazione della scansione orientata alle righe:

  • Query di ricerca point: query che recuperano solo una riga.
  • Query di scansione ridotte: scansioni delle tabelle che analizzano solo poche righe, a meno che non siano state conteggi di ricerca elevati.
  • Query che utilizzano LIMIT.
  • Query che leggono dati con un tasso di abbandono elevato: query in cui oltre il 10% circa del vengono aggiornati di frequente.
  • Query con righe contenenti valori grandi: le righe con valori grandi sono quelle contenente valori superiori a 32.000 byte (precompressione) in un'unica colonna.

Come verificare il metodo di scansione utilizzato da una query

Per verificare se la query utilizza l'elaborazione orientata al batch, l'elaborazione orientata alle righe, o passa automaticamente da un metodo di scansione all'altro:

  1. Vai alla pagina Istanze di Spanner nella console Google Cloud.

    Vai alla pagina Istanze

  2. Fai clic sul nome dell'istanza con la query che vuoi esaminare.

  3. Nella tabella Database, fai clic sul database con la query che ti interessa. per indagare.

  4. Nel menu di navigazione, fai clic su Spanner Studio.

  5. Apri una nuova scheda facendo clic su Nuova scheda dell'editor SQL o Nuova scheda.

  6. Quando viene visualizzato l'editor di query, scrivi la query.

  7. Fai clic su Esegui.

    Spanner esegue la query e mostra i risultati.

  8. Fai clic sulla scheda Spiegazione sotto l'editor query.

    Spanner mostra un visualizzatore del piano di esecuzione del piano di query. Ogni scheda sul grafico rappresenta un iteratore.

  9. Fai clic sulla scheda dell'iteratore Scansione tabella per aprire un riquadro informativo.

    Il riquadro delle informazioni mostra informazioni contestuali sulla scansione selezionata. Il metodo di scansione viene mostrato in questa scheda. Automatico indica che Spanner determina l'analisi . Altri valori possibili sono Vectorized per orientati al batch e Scalar per l'elaborazione orientata alle righe.

    Screenshot di una scheda di scansione di una tabella che mostra il metodo di scansione Automatico

Come applicare in modo forzato il metodo di scansione utilizzato da una query

Per ottimizzare le prestazioni delle query, Spanner sceglie l'analisi ottimale per la tua query. Ti consigliamo di utilizzare questo metodo di scansione predefinito. Tuttavia, potrebbero verificarsi casi in cui potrebbe essere utile applicare tipo di metodo di scansione.

Come applicare la scansione orientata al batch

È possibile applicare l'analisi orientata al batch a livello di tabella e di istruzione.

Per applicare il metodo di scansione orientata al batch a livello di tabella, utilizza un suggerimento per la tabella nella tua query:

GoogleSQL

  SELECT ...
  FROM (t1@{SCAN_METHOD=BATCH} JOIN t2 ON ...)
  WHERE ...

PostgreSQL

  SELECT ...
  FROM (t1/*@ scan_method=batch */ JOIN t2 on ...)
  WHERE ...

Per applicare il metodo di scansione orientata al batch a livello di istruzione, utilizza un hint nella query:

GoogleSQL

  @{SCAN_METHOD=BATCH}
  SELECT ...
  FROM ...
  WHERE ...

PostgreSQL

  /*@ scan_method=batch */
  SELECT ...
  FROM ...
  WHERE ...

Come disattivare la scansione automatica e applicare la scansione orientata alle righe

Anche se sconsigliamo di disattivare il metodo di scansione automatica impostato da Spanner, puoi decidere di disabilitarlo e utilizzare metodo di scansione orientato alle righe per la risoluzione dei problemi, ad esempio la diagnosi una latenza di pochi millisecondi.

Per disabilitare il metodo di scansione automatica e applicare l'elaborazione delle righe nella tabella utilizza un hint di tabella nella query:

GoogleSQL

  SELECT ...
  FROM (t1@{SCAN_METHOD=ROW} JOIN t2 ON ...)
  WHERE ...

PostgreSQL

  SELECT ...
  FROM (t1/*@ scan_method=row */ JOIN t2 on ...)
  WHERE ...

Per disabilitare il metodo di scansione automatica e applicare l'elaborazione delle righe all'istruzione utilizza un suggerimento di istruzioni nella query:

GoogleSQL

  @{SCAN_METHOD=ROW}
  SELECT ...
  FROM ...
  WHERE ...

PostgreSQL

  /*@ scan_method=row */
  SELECT ...
  FROM ...
  WHERE ...

Ottimizza le ricerche di chiavi per l'intervallo

Un uso comune di una query SQL è leggere più righe da Spanner basate su un elenco di chiavi note.

Le seguenti best practice ti aiutano a scrivere query efficienti durante il recupero dei dati in base a un intervallo di chiavi:

  • Se l'elenco delle chiavi è sparso e non adiacente, utilizza parametri di ricerca e UNNEST per creare la tua query.

    Ad esempio, se il tuo elenco di chiavi è {1, 5, 1000}, scrivi la query come segue:

    GoogleSQL

    SELECT *
    FROM Table AS t
    WHERE t.Key IN UNNEST (@KeyList)
    

    PostgreSQL

    SELECT *
    FROM Table AS t
    WHERE t.Key IN UNNEST ($1)
    

    Note:

    • L'operatore di array UNNEST appiattisce un di input in righe di elementi.

    • Il parametro di query, che è @KeyList per GoogleSQL e $1 per PostgreSQL, possono accelerare la query come discusso della best practice precedente.

  • Se l'elenco delle chiavi è adiacente ed entro un intervallo, specifica il valore minimo e limiti più elevati dell'intervallo di chiavi nella clausola WHERE.

    Ad esempio, se l'elenco di chiavi è {1,2,3,4,5}, crea la query come che segue:

    GoogleSQL

    SELECT *
    FROM Table AS t
    WHERE t.Key BETWEEN @min AND @max
    

    PostgreSQL

    SELECT *
    FROM Table AS t
    WHERE t.Key BETWEEN $1 AND $2
    

    Questa query è più efficiente solo se le chiavi nell'intervallo di chiavi sono sono adiacenti. In altre parole, se il tuo elenco di chiavi è {1, 5, 1000}, non specificare il limite minimo e quello più alto come nella query precedente, in quanto la query risultante analizza tutti i valori compresi tra 1 e 1000.

join di Optimize

Le operazioni di join possono essere costose perché possono aumenta il numero di righe che deve essere analizzata dalla query, ottenendo per eseguire query più lente. Oltre alle tecniche che utilizzi abitualmente in altri database relazionali per ottimizzare le query di join, ecco alcune best per un JOIN più efficiente quando si utilizza Spanner SQL:

  • Se possibile, unisci i dati in tabelle con interleaving in base alla chiave primaria. Ad esempio:

    SELECT s.FirstName, a.ReleaseDate
    FROM Singers AS s JOIN Albums AS a ON s.SingerId = a.SingerId;
    

    È garantita la presenza fisica delle righe nella tabella con interleaving Albums archiviati nelle stesse suddivisioni della riga padre in Singers, come discusso in Schema e modello dei dati. Di conseguenza, i join possono essere completati localmente senza inviare molti dati attraverso la rete.

  • Utilizza l'istruzione di join se vuoi forzare l'ordine del join. Per esempio:

    GoogleSQL

    SELECT *
    FROM Singers AS s JOIN@{FORCE_JOIN_ORDER=TRUE} Albums AS a
    ON s.SingerId = a.Singerid
    WHERE s.LastName LIKE '%x%' AND a.AlbumTitle LIKE '%love%';
    

    PostgreSQL

    SELECT *
    FROM Singers AS s JOIN/*@ FORCE_JOIN_ORDER=TRUE */ Albums AS a
    ON s.SingerId = a.Singerid
    WHERE s.LastName LIKE '%x%' AND a.AlbumTitle LIKE '%love%';
    

    L'istruzione di join FORCE_JOIN_ORDER indica a Spanner di utilizzare all'ordine di join specificato nella query (vale a dire Singers JOIN Albums, non Albums JOIN Singers). I risultati restituiti sono gli stessi, indipendentemente dal nell'ordine scelto da Spanner. Tuttavia, potresti voler utilizzare questo join se nel piano di query noti che Spanner è cambiato l'ordine di join e causato conseguenze indesiderate, come o ha perso opportunità di cercare righe.

  • Utilizza un'istruzione di join per scegliere un'implementazione di join. Quando utilizzi SQL quando esegui una query su più tabelle, Spanner usa automaticamente un metodo di join che potrebbero rendere la query più efficiente. Tuttavia, Google consiglia da testare con diversi algoritmi di join. Scelta del giusto algoritmo di join può migliorare la latenza, il consumo di memoria o entrambi. Questa query dimostra la sintassi per usare un'istruzione JOIN con il suggerimento JOIN_METHOD per scegliere un HASH JOIN:

    GoogleSQL

    SELECT *
    FROM Singers s JOIN@{JOIN_METHOD=HASH_JOIN} Albums AS a
    ON a.SingerId = a.SingerId
    

    PostgreSQL

    SELECT *
    FROM Singers s JOIN/*@ JOIN_METHOD=HASH_JOIN */ Albums AS a
    ON a.SingerId = a.SingerId
    
  • Se usi un HASH JOIN o APPLY JOIN e hai un WHERE molto selettiva da un lato di JOIN, inserisci la tabella che produce il numero più basso di righe come prima tabella in FROM del join. Questa struttura è utile perché attualmente in HASH JOIN, Spanner sceglie sempre la tabella laterale sinistra come build e tavolo laterale destro come sonda. Allo stesso modo, per APPLY JOIN, Spanner sceglie il tavolino di sinistra come esterno e quello di destra come interno. Scopri di più su questi tipi di join: Hash join e Richiedi adesione.

  • Per le query fondamentali per il carico di lavoro, specifica la query più performante e l'ordine di join nelle istruzioni SQL per una maggiore coerenza delle prestazioni.

Evitare letture di grandi dimensioni all'interno delle transazioni di lettura/scrittura

Le transazioni di lettura/scrittura consentono una sequenza di zero o più legge o query SQL e può includere un insieme di mutazioni prima di una chiamata eseguire il commit. Per mantenere la coerenza dei dati, Spanner acquisisce i blocchi durante la lettura e la scrittura di righe nelle tabelle e negli indici. Per Per ulteriori informazioni sul blocco, consulta l'argomento Life of letture e scritture.

A causa del funzionamento del blocco in Spanner, l'esecuzione di una lettura o di un SQL query che legge un numero elevato di righe (ad esempio SELECT * FROM Singers) significa che nessun'altra transazione può scrivere nelle righe che hai letto la transazione è stata confermata o interrotta.

Inoltre, poiché la transazione sta elaborando un numero elevato di righe, richiedere più tempo rispetto a una transazione che legge un intervallo di righe molto più ridotto (ad esempio SELECT LastName FROM Singers WHERE SingerId = 7), che ulteriormente aggrava il problema e riduce la velocità effettiva del sistema.

Quindi, cerca di evitare letture di grandi dimensioni (ad esempio, scansioni complete di tabelle o join massicci operazioni) nelle tue transazioni, a meno che tu non sia disposto ad accettare e la velocità effettiva effettiva.

In alcuni casi, il seguente pattern può produrre risultati migliori:

  1. Esegui letture di grandi dimensioni all'interno di una transazione di sola lettura. Le transazioni di sola lettura consentono una maggiore velocità effettiva aggregata perché non utilizzare blocchi.
  2. (Facoltativo) Esegui le eventuali elaborazioni richieste per i dati che hai appena letto.
  3. Avviare una transazione di lettura/scrittura.
  4. Verifica che le righe critiche non abbiano modificato i valori dall'esecuzione la transazione di sola lettura del passaggio 1.
    • Se le righe sono state modificate, esegui il rollback della transazione e ricomincia da passaggio 1.
    • Se tutto sembra a posto, commetti le tue mutazioni.

Un modo per evitare letture di grandi dimensioni in lettura/scrittura transazioni consiste nell'esaminare i piani di esecuzione generati dalle tue query.

Usa ORDER BY per assicurarti che l'ordine dei risultati SQL

Se prevedi un determinato ordinamento per i risultati di una query SELECT, includere esplicitamente la clausola ORDER BY. Ad esempio, se vuoi elenca tutti i cantanti in ordine di chiave primaria, utilizza questa query:

SELECT * FROM Singers
ORDER BY SingerId;

Spanner garantisce l'ordinamento dei risultati solo se la clausola ORDER BY è presente nella query. In altre parole, considera questa query senza il valore ORDER BY:

SELECT * FROM Singers;

Spanner non garantisce che i risultati di questa query vengano nell'ordine chiave primaria. Inoltre, l'ordine dei risultati può cambiare in qualsiasi momento e non è garantita in modo coerente tra le varie chiamate. Se una query ha una clausola ORDER BY e Spanner usa un indice che fornisce nell'ordine richiesto, Spanner non ordina i dati in modo esplicito. Pertanto, non devi preoccuparti dell'impatto sul rendimento derivante dall'inclusione di questa clausola. Puoi controllare se un'operazione di ordinamento esplicita è inclusa nell'esecuzione esaminando il piano di query.

Utilizza STARTS_WITH al posto di LIKE

Poiché Spanner non valuta i pattern LIKE con parametri fino a quando è necessario leggere tutte le righe e valutarle rispetto Espressione LIKE per filtrare le righe che non corrispondono.

Quando un pattern LIKE ha il formato foo% (ad esempio, inizia con un stringa e termina con una singola percentuale con carattere jolly) e la colonna è indicizzata, utilizza STARTS_WITH anziché LIKE. Questo consente a Spanner di ottimizzare in modo più efficace l'esecuzione della query e il piano d'azione.

Sconsigliati:

GoogleSQL

SELECT a.AlbumTitle FROM Albums a
WHERE a.AlbumTitle LIKE @like_clause;

PostgreSQL

SELECT a.AlbumTitle FROM Albums a
WHERE a.AlbumTitle LIKE $1;

Consigliato:

GoogleSQL

SELECT a.AlbumTitle FROM Albums a
WHERE STARTS_WITH(a.AlbumTitle, @prefix);

PostgreSQL

SELECT a.AlbumTitle FROM Albums a
WHERE STARTS_WITH(a.AlbumTitle, $2);

Utilizza timestamp di commit

Se la tua applicazione deve eseguire query su dati scritti dopo un determinato periodo di tempo, Aggiungere colonne di timestamp di commit alle tabelle pertinenti. Timestamp del commit abilitare un'ottimizzazione Spanner che può ridurre l'I/O di query le cui clausole WHERE limitano i risultati alle righe scritte più di recente rispetto a un'ora specifica.

Scopri di più su questa ottimizzazione con database di dialetti GoogleSQL o con database di dialetti PostgreSQL.