Versioni dello strumento di ottimizzazione delle query Spanner
Mantieni tutto organizzato con le raccolte
Salva e classifica i contenuti in base alle tue preferenze.
Questa pagina descrive e fornisce una cronologia delle varie versioni dell'ottimizzatore delle query Spanner. La versione predefinita corrente è 7.
Per scoprire di più sullo Strumento di ottimizzazione delle query, consulta Informazioni sullo Strumento di ottimizzazione delle query.
Spanner implementa gli aggiornamenti dello strumento di ottimizzazione delle query come nuove versioni dello strumento. Per impostazione predefinita, ogni database inizia a utilizzare la versione più recente dell'ottimizzatore non prima di 30 giorni dal rilascio della versione.
Se utilizzi un database in dialetto GoogleSQL, puoi gestire la versione dell'ottimizzatore delle query impiegata dalle tue query. Prima di eseguire l'commit alla versione più recente, puoi confrontare i profili di rendimento delle query tra le versioni precedenti e la versione più recente. Per scoprire di più, consulta Gestire lo strumento di ottimizzazione delle query.
Cronologia delle versioni dello strumento di ottimizzazione delle query
Di seguito è riportato un riepilogo degli aggiornamenti apportati all'ottimizzatore delle query in ogni release.
Versione 8: 28 ottobre 2024 (ultima)
Le clausole WITH vengono prese in considerazione quando si scelgono i piani in base al costo.
Miglioramento delle prestazioni delle query di ricerca indicizzata e di applicazione incrociata distribuite.
Riordinamento JOIN migliorato.
Miglioramento delle prestazioni delle query con clausole IN (...) di grandi dimensioni.
Miglioramento delle prestazioni di GROUP BY in alcuni casi.
Altri miglioramenti, tra cui una gestione più efficiente delle query con LIMIT, le chiavi esterne e la selezione degli indici.
Versione 7: 22 maggio 2024 (valore predefinito)
È stato aggiunto il supporto per la selezione in base al costo dei piani di unione di indici.
È stato aggiunto il supporto per la selezione intelligente dei piani di ricerca rispetto a quelli di scansione in base alle statistiche per le query che non dispongono di predicati cercabili per tutte le parti chiave.
È stato aggiunto il supporto per la selezione basata sui costi delle unioni con hash.
Versione 6: 11 settembre 2023
Miglioramento dell'applicazione di limiti e della definizione di predicati tramite unioni esterne complete.
Modello di costo e stima della cardinalità migliorati.
È stata attivata l'ottimizzazione in base al costo per le query DML.
Versione 5: 15 luglio 2022
Modello di costo migliorato per la selezione degli indici, la gestione della distribuzione, il posizionamento dell'ordinamento e la selezione di GROUP BY.
È stato aggiunto il supporto per la selezione dell'algoritmo di join basato sul costo che sceglie tra join con hash e join con applicazione. L'unione per accodamento richiede ancora l'utilizzo di un suggerimento di query.
È stato aggiunto il supporto della commutatività delle unioni basate sui costi.
Versione 4: 1° marzo 2022
Miglioramenti alla selezione dell'indice secondario.
È stato migliorato l'utilizzo dell'indice secondario in un join tra tabelle interlacciate.
È stato migliorato l'utilizzo dell'indice secondario di copertura.
Miglioramento della selezione dell'indice quando le statistiche dello strumento di ottimizzazione sono obsolete.
Preferisci gli indici secondari con predicati sulle colonne principali indicizzate anche se le statistiche dell'ottimizzatore non sono disponibili o se la tabella di base è piccola.
Viene introdotta l'unione con hash a passaggio singolo, abilitata dal nuovo suggerimentohash_join_execution.
Il numero di esecuzioni del figlio destro dell'unione hash è maggiore
del numero di esecuzioni dell'operatore di unione hash.
Anche la latenza del nodo figlio destro dell'operatore di join con hash è elevata.
Per impostazione predefinita (hash_join_execution=multi_pass), se l'input lato build della join di hash è troppo grande per essere inserito in memoria, il lato build viene suddiviso in più batch e potremmo eseguire la scansione del lato probe più volte. Con la nuova modalità (hash_join_execution=one_pass), un join di hashing viene trasferito sul disco se il relativo input lato build non può essere memorizzato in memoria e la scansione del lato probe viene sempre eseguita una sola volta.
Un miglioramento nella selezione del numero di chiavi utilizzate per la ricerca.
Versione 3: 1° agosto 2021
Aggiunge un nuovo algoritmo di join, la join di unione, abilitato utilizzando un nuovo valore dell'istruzione di suggerimento query JOIN METHOD.
Viene introdotto l'operatore unione per unione distribuita, che è attivato per impostazione predefinita, se applicabile. Questa operazione
migliora le prestazioni delle query.
Un piccolo miglioramento del rendimento di una scansione in un GROUP BY quando
non è presente un valore aggregato MAX o MIN (o HAVING MAX/MAX) nell'elenco SELECT.
Prima di questa modifica, Spanner caricava la colonna aggiuntiva non raggruppata anche se non era richiesta dalla query.
Prima di questa modifica, la seguente query avrebbe caricato la colonna c anche se non è richiesta dalla query.
SELECTa,bFROMmyTableGROUPBYa,b
Migliora le prestazioni di alcune query con LIMIT quando è presente un operatore di applicazione incrociata introdotto dalle unioni e la query richiede risultati ordinati con LIMIT. Dopo questa modifica, l'ottimizzatore applica prima l'ordinamento con il limite sul lato di input dell'applicazione incrociata.
Migliora le prestazioni delle query inviando più calcoli tramite JOIN.
Esegue più calcoli che possono includere una sottoquery o la costruzione di una struttura tramite join. Ciò migliora le prestazioni delle query in diversi modi, ad esempio:
È possibile eseguire più calcoli in modo distribuito e anche altre operazioni
che dipendono dai calcoli inviati possono essere spostate verso il basso. Ad esempio, se la query ha un limite e l'ordinamento dipende da questi calcoli, il limite può essere applicato anche tramite l'unione.
Aggiunge ottimizzazioni nella selezione degli indici.
Migliora il rendimento dei predicati REGEXP_CONTAINS e LIKE in determinate circostanze.
Migliora le prestazioni di una scansione sotto un GROUP BY in determinate situazioni.
Versione 1: 18 giugno 2019
Include molte ottimizzazioni basate su regole, ad esempio pushdown dei predicati, pushdown del limite, join ridondanti e rimozione di espressioni ridondanti, per citarne alcuni.
Utilizza le statistiche sui dati utente per selezionare l'indice da utilizzare per accedere a ogni tabella.
[[["Facile da capire","easyToUnderstand","thumb-up"],["Il problema è stato risolto","solvedMyProblem","thumb-up"],["Altra","otherUp","thumb-up"]],[["Difficile da capire","hardToUnderstand","thumb-down"],["Informazioni o codice di esempio errati","incorrectInformationOrSampleCode","thumb-down"],["Mancano le informazioni o gli esempi di cui ho bisogno","missingTheInformationSamplesINeed","thumb-down"],["Problema di traduzione","translationIssue","thumb-down"],["Altra","otherDown","thumb-down"]],["Ultimo aggiornamento 2025-09-05 UTC."],[],[],null,["# Spanner query optimizer versions\n\nThis page describes and provides a history of the various Spanner query\noptimizer versions. The current default version is 7.\nTo learn more about the query optimizer, see [About query optimizer](/spanner/docs/query-optimizer/overview).\n\nSpanner rolls out query optimizer updates as new query\noptimizer versions. By default, each database starts using the latest version of\nthe optimizer no sooner than 30 days after that version has been released.\n\nIf you're using a GoogleSQL-dialect database, you can manage the query optimizer version\nthat your queries use. Before committing to the latest version, you can compare\nquery performance profiles between earlier versions and the latest version. To\nlearn more, see [Manage the query optimizer](/spanner/docs/query-optimizer/manage-query-optimizer).\n\nQuery optimizer version history\n-------------------------------\n\nThe following is a summary of the updates made to the query optimizer in each\nrelease.\n\n\u003cbr /\u003e\n\n### Version 8: October 28th, 2024 (latest)\n\n- `WITH` clauses are considered when making cost-based plan choices.\n\n- Improved performance of distributed cross apply and indexed lookup queries.\n\n- Improved `JOIN` reordering.\n\n- Improved performance of queries with large `IN (...)` clauses.\n\n- Improved `GROUP BY` performance in certain cases.\n\n- Other improvements including more efficient handling of queries with `LIMIT`,\n foreign keys, and index selection.\n\n### Version 7: May 22nd, 2024 (default)\n\n- Added support for cost-based selection of index union plans.\n\n- Added support for the smart selection of seek versus scan plans based on\n statistics for queries that don't have seekable predicates for all key parts.\n\n- Added support for cost-based selection of hash joins.\n\n### Version 6: September 11th, 2023\n\n- Improved limit pushing and predicate pushing through full outer joins.\n\n- Improved cardinality estimation and cost model.\n\n- Enabled cost-based optimization for DML queries.\n\n### Version 5: July 15th, 2022\n\n- Improved cost model for index selection, distribution management, sort\n placement and `GROUP BY` selection.\n\n- Added support for cost-based join algorithm selection that chooses between\n hash and apply join. Merge join still requires using a query hint.\n\n- Added support for cost-based join commutativity.\n\n### Version 4: March 1st, 2022\n\n- Improvements to secondary index selection.\n\n - Improved secondary index usage under a join between interleaved tables.\n - Improved covering secondary index usage.\n - Improved index selection when optimizer statistics are outdated.\n - Prefer secondary indexes with predicates on leading indexed columns even if the optimizer statistics are not available or report the base table is small.\n- Introduces single pass hash join, enabled by the new hint\n `hash_join_execution`.\n\n Join Hint: \n\n ### GoogleSQL\n\n SELECT ...\n FROM (...)\n JOIN@{join_method=hash_join, hash_join_execution=one_pass} (...)\n\n ### PostgreSQL\n\n SELECT ...\n FROM (...)\n JOIN/*@ join_method=hash_join, hash_join_execution=one_pass */ (...)\n\n The new mode is beneficial when the [build side input of the hash join](/spanner/docs/query-execution-operators#hash-join)\n is large. One pass hash join is expected to have better performance when you\n observe the following in the [query execution profile](/spanner/docs/tune-query-with-visualizer):\n - The number of executions on the right child of the hash join is larger than the number of executions on the hash join operator.\n - The latency on the right child of the hash join operator is also high.\n\n By default (`hash_join_execution=multi_pass`), if the build side input of\n the hash join is too large to fit in memory, the build side is split into\n multiple batches and we might scan the probe side multiple times. With the\n new mode (`hash_join_execution=one_pass`), a hash join will spill to disk if\n its build side input cannot fit in memory and will always scan the probe\n side only once.\n- An improvement in selecting how many keys are used for seeking.\n\n### Version 3: August 1st, 2021\n\n- Adds a new join algorithm, merge join, enabled using a new [JOIN METHOD](/spanner/docs/reference/standard-sql/query-syntax#join-methods)\n query hint value.\n\n Statement hint: \n\n ### GoogleSQL\n\n @{join_method=merge_join}\n SELECT ...\n\n ### PostgreSQL\n\n /*@ join_method=merge_join */\n SELECT ...\n\n Join hint: \n\n ### GoogleSQL\n\n SELECT ...\n FROM (...)\n JOIN@{join_method=merge_join} (...)\n\n ### PostgreSQL\n\n SELECT ...\n FROM (...)\n JOIN/*@ join_method=merge_join */ (...)\n\n- Adds a new join algorithm, push broadcast hash join, enabled using a new\n [JOIN METHOD](/spanner/docs/reference/standard-sql/query-syntax#join-methods) query hint value.\n\n Join hint: \n\n ### GoogleSQL\n\n SELECT ...\n FROM (...)\n JOIN@{join_method=push_broadcast_hash_join} (...)\n\n ### PostgreSQL\n\n SELECT ...\n FROM (...)\n JOIN/*@ join_method=push_broadcast_hash_join} */ (...)\n\n- Introduces the [distributed merge union](/spanner/docs/query-execution-operators#distributed-merge-union)\n operator, which is enabled by default when applicable. This operation\n improves the performance of queries.\n\n- A small improvement to the performance of a scan under a `GROUP BY` when\n there is no MAX or MIN aggregate (or HAVING MAX/MAX) in the SELECT list.\n Prior to this change, Spanner loaded the extra non-grouped\n column even if it was not required by the query.\n\n For example, consider the following table: \n\n ### GoogleSQL\n\n CREATE TABLE myTable(\n a INT64,\n b INT64,\n c INT64,\n d INT64)\n PRIMARY KEY (a, b, c);\n\n ### PostgreSQL\n\n CREATE TABLE myTable(\n a bigint,\n b bigint,\n c bigint,\n d bigint,\n PRIMARY KEY(a, b, c)\n );\n\n Prior to this change, the following query would have loaded column `c` even\n though it is not required by the query. \n\n SELECT a, b\n FROM myTable\n GROUP BY a, b\n\n- Improves the performance of some queries with `LIMIT` when there is a\n cross apply operator introduced by joins and the query asks for sorted\n results with LIMIT. After this change, the optimizer applies the sorting\n with the limit on the input side of cross apply first.\n\n Example: \n\n ### GoogleSQL\n\n SELECT a2.*\n FROM Albums@{FORCE_INDEX=_BASE_TABLE} a1\n JOIN Albums@{FORCE_INDEX=_BASE_TABLE} a2 USING(SingerId)\n ORDER BY a1.AlbumId\n LIMIT 2;\n\n ### PostgreSQL\n\n SELECT a2.*\n FROM albums/*@ force_index=_base_table */ a1\n JOIN albums/*@ force_index=_base_table */ a2 USING(singerid)\n ORDER BY a1.albumid\n LIMIT 2;\n\n- Improves query performance by pushing more computations through `JOIN`.\n\n Pushes more computations which may include a subquery or struct construction\n through join. That improves the query performance in a few ways such as:\n More computations can be done in a distributed fashion and more operations\n that depend on the pushed computations can be pushed down as well. For\n example, the query has a limit and the sort order depends on those\n computations, then the limit can be pushed through join as well.\n\n Example: \n\n SELECT\n t.ConcertDate,\n (\n SELECT COUNT(*) FROM UNNEST(t.TicketPrices) p WHERE p \u003e 10\n ) AS expensive_tickets,\n u.VenueName\n FROM Concerts t\n JOIN Venues u ON t.VenueId = u.VenueId\n ORDER BY expensive_tickets\n LIMIT 2;\n\n\u003cbr /\u003e\n\n### Version 2: March 1st, 2020\n\n- Adds optimizations in index selection.\n- Improves the performance of `REGEXP_CONTAINS` and `LIKE` predicates under certain circumstances.\n- Improves the performance of a scan under a `GROUP BY` in certain situations.\n\n\u003cbr /\u003e\n\n### Version 1: June 18th, 2019\n\n- Includes many rule based optimizations such as predicate pushdown, limit\n pushdown, redundant join and redundant expression removal, to name a few.\n\n- Uses statistics on user data to select which index to use to access each\n table.\n\nWhat's next\n-----------\n\n- To learn more about the query optimizer, see [About query optimizer](/spanner/docs/query-optimizer/overview).\n- To manage both the optimizer version and statistics package for your scenario, see [Manage the query optimizer](/spanner/docs/query-optimizer/manage-query-optimizer)."]]