Como se describe en Planes de ejecución de consultas, el compilador de SQL transforma una instrucción de SQL en un plan de ejecución de consultas, que se usa para obtener los resultados de la consulta. En esta página, se describen las prácticas recomendadas para construir sentencias de SQL que ayuden a Spanner a encontrar planes de ejecución eficientes. Consulta la guía de [Ajuste de consultas][query_tuning] para obtener ayuda para mejorar el rendimiento de las consultas.
Las sentencias de SQL de ejemplo que se muestran en esta página usan el siguiente esquema de ejemplo:
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;
Para obtener la referencia completa de SQL, consulta Sintaxis de las declaraciones, Funciones y operadores y Estructura léxica y sintaxis.
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;
Para obtener más información, consulta El lenguaje PostgreSQL en Spanner.
Usa parámetros de consulta
Spanner admite parámetros de consulta para aumentar el rendimiento y ayudar a evitar la inyección de SQL cuando las consultas se construyen con entradas del usuario. Puedes usar parámetros de consulta como sustitutos de expresiones arbitrarias, pero no como sustitutos de identificadores, nombres de columnas, nombres de tablas ni otras partes de la consulta.
Los parámetros pueden aparecer en cualquier lugar donde se espere un valor literal. El mismo nombre de parámetro se puede usar más de una vez en una sola instrucción de SQL.
En resumen, los parámetros de consulta admiten la ejecución de consultas de las siguientes maneras:
- Planes optimizados previamente: Las consultas que usan parámetros se pueden ejecutar más rápido en cada invocación, ya que la parametrización facilita que Spanner almacene en caché el plan de ejecución.
- Composición de consultas simplificada: No necesitas escapar los valores de cadena cuando los proporcionas en los parámetros de consulta. Los parámetros de consulta también reducen el riesgo de errores de sintaxis.
- Seguridad: Los parámetros de consulta hacen que tus consultas sean más seguras, ya que te protegen de varios ataques de inyección de SQL. Esta protección es importante en particular para las consultas que creas a partir de las entradas del usuario.
Para mejorar el rendimiento, Spanner convierte los valores literales codificados en SQL en parámetros si el plan de ejecución de consultas óptimo no depende de los valores literales específicos. Esto permite que Spanner reduzca la latencia y los costos de CPU almacenando en caché y reutilizando el plan de consulta. Sin embargo, esto no ofrece las mismas protecciones contra la inyección de SQL ni los beneficios de una composición de consultas más sencilla. La práctica recomendada es usar parámetros de consulta en el código de la aplicación.
Comprende cómo Spanner ejecuta consultas
Spanner te permite consultar bases de datos con sentencias de SQL declarativas que especifican qué datos deseas recuperar. Si quieres comprender cómo Spanner obtiene los resultados, examina el plan de ejecución de la consulta. Un plan de ejecución de consultas muestra el costo de procesamiento asociado con cada paso de la consulta. Con esos costos, puedes depurar los problemas de rendimiento de las consultas y optimizarlas. Para obtener más información, consulta Planes de ejecución de consultas.
Puedes recuperar planes de ejecución de consultas a través de la consola de Google Cloud o de las bibliotecas cliente.
Para obtener un plan de ejecución de consultas para una consulta específica con la consola deGoogle Cloud , sigue estos pasos:
Abre la página Instancias de Spanner.
Selecciona los nombres de la instancia de Spanner y la base de datos que deseas consultar.
Haz clic en Spanner Studio en el panel de navegación izquierdo.
Escribe la consulta en el campo de texto y, luego, haz clic en Ejecutar consulta.
Haz clic en Explicación
. La consola de Google Cloud muestra un plan de ejecución visual para tu consulta.
Para obtener más información sobre cómo comprender los planes visuales y usarlos para depurar tus consultas, consulta Ajusta una consulta con el visualizador del plan de consultas.
También puedes ver muestras de planes de consultas históricos y comparar el rendimiento de una consulta a lo largo del tiempo para ciertas consultas. Para obtener más información, consulta Planes de consultas muestreados.
Usa índices secundarios
Al igual que otras bases de datos relacionales, Spanner ofrece índices secundarios, que puedes usar para recuperar datos con una instrucción de SQL o la interfaz de lectura de Spanner. Usar un índice secundario en una consulta en SQL te permite especificar cómo quieres que Spanner obtenga los resultados. Especificar un índice secundario puede acelerar la ejecución de consultas.
Por ejemplo, supongamos que deseas recuperar los IDs de todos los cantantes con un apellido específico. Una forma de escribir una consulta en SQL de este tipo es la siguiente:
SELECT s.SingerId
FROM Singers AS s
WHERE s.LastName = 'Smith';
Esta consulta devolvería los resultados que esperas, pero podría tardar mucho
tiempo en devolverlos. El tiempo dependería de la cantidad de filas en la tabla Singers y de cuántas satisfacen el predicado WHERE s.LastName = 'Smith'.
Si no hay un índice secundario que contenga la columna LastName para leer, el plan de consulta leería toda la tabla Singers para encontrar las filas que coincidan con el predicado. La lectura de la tabla completa se denomina análisis completo de la tabla. Un análisis de tabla completo
es una forma costosa de obtener los resultados cuando la tabla contiene solo un
pequeño porcentaje de Singers con ese apellido.
Para mejorar el rendimiento de esta consulta, define un índice secundario en la columna de apellido:
CREATE INDEX SingersByLastName ON Singers (LastName);
Debido a que el índice secundario SingersByLastName contiene la columna de la tabla indexada
LastName y la columna de clave primaria SingerId, Spanner
puede recuperar todos los datos de la tabla de índice mucho más pequeña en lugar de analizar la
tabla Singers completa.
En esta situación, Spanner usa automáticamente el índice secundario
SingersByLastName cuando ejecuta la consulta (siempre que hayan pasado tres días
desde la creación de la base de datos; consulta Nota sobre las bases de datos nuevas).
Sin embargo, es mejor indicarle de forma explícita a Spanner que use ese índice
especificando una directiva de índice en la cláusula 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';
Si usas esquemas con nombre,
usa la siguiente sintaxis para la cláusula FROM:
GoogleSQL
FROM NAMED_SCHEMA_NAME.TABLE_NAME@{FORCE_INDEX="NAMED_SCHEMA_NAME.TABLE_INDEX_NAME"}
PostgreSQL
FROM NAMED_SCHEMA_NAME.TABLE_NAME /*@ FORCE_INDEX = TABLE_INDEX_NAME */
Supongamos que también deseas recuperar el nombre del cantante, además del ID. Aunque la columna FirstName no está incluida en el índice, aún debes especificar la directiva de índice como antes:
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';
Aún obtienes un beneficio de rendimiento por usar el índice, ya que
Spanner no necesita realizar un análisis de tabla completo cuando ejecuta el
plan de consulta. En su lugar, selecciona el subconjunto de filas que cumplen con el predicado
del índice SingersByLastName y, luego, realiza una búsqueda en la tabla base
Singers para recuperar el nombre solo de ese subconjunto de filas.
Si deseas que Spanner no tenga que recuperar ninguna fila de la tabla
base, puedes almacenar una copia de la columna FirstName en el índice:
GoogleSQL
CREATE INDEX SingersByLastName ON Singers (LastName) STORING (FirstName);
PostgreSQL
CREATE INDEX SingersByLastName ON Singers (LastName) INCLUDE (FirstName);
Usar una cláusula STORING (para el dialecto de GoogleSQL) o una cláusula INCLUDE (para el dialecto de PostgreSQL) como esta cuesta almacenamiento adicional, pero
proporciona las siguientes ventajas:
- Las consultas en SQL que usan el índice y seleccionan las columnas almacenadas en la cláusula
STORINGoINCLUDEno requieren una unión adicional a la tabla base. - Las llamadas de lectura que usan el índice pueden leer las columnas almacenadas en la cláusula
STORINGoINCLUDE.
En los ejemplos anteriores, se ilustra cómo los índices secundarios pueden acelerar las consultas
cuando las filas elegidas por la cláusula WHERE de una consulta se pueden identificar con rapidez
con el índice secundario.
Otro caso en el que los índices secundarios pueden ofrecer beneficios de rendimiento es para ciertas consultas que devuelven resultados ordenados. Por ejemplo, supongamos que deseas recuperar todos los títulos de álbumes y sus fechas de lanzamiento en orden ascendente de fecha de lanzamiento y orden descendente de título de álbum. Podrías escribir una consulta en SQL de la siguiente manera:
SELECT a.AlbumTitle, a.ReleaseDate
FROM Albums AS a
ORDER BY a.ReleaseDate, a.AlbumTitle DESC;
Sin un índice secundario, esta consulta requiere un paso de clasificación potencialmente costoso en el plan de ejecución. Para acelerar la ejecución de consultas, define este índice secundario:
CREATE INDEX AlbumsByReleaseDateTitleDesc on Albums (ReleaseDate, AlbumTitle DESC);
Luego, vuelve a escribir la consulta para usar el índice secundario:
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;
Esta definición de consulta y de índice cumple con los siguientes criterios:
- Para quitar el paso de ordenamiento, asegúrate de que la lista de columnas en la cláusula
ORDER BYsea un prefijo de la lista de claves de índice. - Para evitar volver a unirte desde la tabla base para recuperar las columnas faltantes, asegúrate de que el índice cubra todas las columnas de la tabla que usa la consulta.
Aunque los índices secundarios pueden acelerar las consultas comunes, agregarlos puede aumentar la latencia de tus operaciones de confirmación, ya que cada índice secundario suele requerir que se incluya un nodo adicional en cada confirmación. Para la mayoría de las cargas de trabajo, es suficiente tener algunos índices secundarios. Sin embargo, debes considerar si te importa más la latencia de lectura o de escritura, y qué operaciones son más críticas para tu carga de trabajo. Compara tu carga de trabajo para asegurarte de que funcione como se espera.
Para obtener la referencia completa de los índices secundarios, consulta la página sobre los índices secundarios.
Optimiza las búsquedas de claves de rango
Un uso común de una consulta en SQL es leer varias filas de Spanner en función de una lista de claves conocidas.
Las siguientes prácticas recomendadas te ayudan a escribir consultas eficientes cuando recuperas datos por un rango de claves:
Si la lista de claves es dispersa y no adyacente, usa los parámetros de consulta y
UNNESTpara construir tu consulta.Por ejemplo, si tu lista de claves es
{1, 5, 1000}, escribe la consulta de la manera siguiente:GoogleSQL
SELECT * FROM Table AS t WHERE t.Key IN UNNEST (@KeyList)
PostgreSQL
SELECT * FROM Table AS t WHERE t.Key IN UNNEST ($1)
Notas:
El operador UNNEST de array compacta un array de entrada en filas de elementos.
El parámetro de consulta, que es
@KeyListpara GoogleSQL y$1para PostgreSQL, puede acelerar tu consulta, como se analiza en la práctica recomendada anterior.Es mejor usar un UNNEST con un solo parámetro, en lugar de OR con varios parámetros.
Si la lista de claves es adyacente y está dentro de un rango, especifica los límites inferior y superior del rango de claves en la cláusula
WHERE.Por ejemplo, si tu lista de claves es
{1,2,3,4,5}, construye la consulta de la siguiente manera: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
Esta consulta solo es más eficiente si las claves del rango de claves son adyacentes. En otras palabras, si tu lista de claves es
{1, 5, 1000}, no especifiques los límites inferior y superior como en la consulta anterior, ya que la consulta resultante analizaría todos los valores entre 1 y 1000.
Optimiza las uniones
Las operaciones de unión pueden ser costosas porque pueden aumentar de forma significativa la cantidad de filas que tu consulta necesita analizar, lo que genera consultas más lentas. Además de las técnicas que sueles usar en otras bases de datos relacionales para optimizar las consultas de unión, estas son algunas prácticas recomendadas para una UNIÓN más eficiente cuando se usa SQL de Spanner:
- Si es posible, une los datos de las tablas intercaladas por clave primaria. Por ejemplo:
SELECT s.FirstName, a.ReleaseDate FROM Singers AS s JOIN Albums AS a ON s.SingerId = a.SingerId;
The rows in the interleaved table `Albums` are physically
stored in the same splits as the parent row in `Singers`, as discussed in
[Schema and Data Model](/spanner/docs/schema-and-data-model). Therefore, joins can be
completed locally without sending lots of data across the network.
Usa la directiva de unión si deseas forzar el orden de la unión. Por ejemplo:
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%';
La directiva de unión
FORCE_JOIN_ORDERle indica a Spanner que use el orden de unión especificado en la consulta (es decir,Singers JOIN Albums, noAlbums JOIN Singers). Los resultados que se muestran son los mismos, independientemente del orden que elija Spanner. Sin embargo, es posible que desees usar esta directiva de unión si notas en el plan de consulta que Spanner cambió el orden de unión y causó consecuencias no deseadas, como resultados intermedios más grandes, o si perdió oportunidades para buscar filas.Usa una directiva de unión para elegir una implementación de unión. Cuando usas SQL para consultar varias tablas, Spanner utiliza automáticamente un método de unión que probablemente haga que la consulta sea más eficiente. Sin embargo, Google te aconseja que realices pruebas con diferentes algoritmos de unión. Elegir el algoritmo de unión correcto puede mejorar la latencia, el consumo de memoria o ambos. En esta consulta, se muestra la sintaxis para usar una directiva JOIN con la sugerencia
JOIN_METHODpara elegir unHASH 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
Si usas un
HASH JOINoAPPLY JOINy tienes una cláusulaWHEREque es muy selectiva en un lado de tuJOIN, coloca la tabla que produce la menor cantidad de filas como la primera tabla en la cláusulaFROMde la unión. Esta estructura ayuda porque, enHASH JOIN, Spanner siempre elige la tabla del lado izquierdo como compilación y la tabla del lado derecho como sondeo. De manera similar, paraAPPLY JOIN, Spanner elige la tabla del lado izquierdo como externa y la tabla del lado derecho como interna. Obtén más información sobre estos tipos de uniones: [Unión hash][hash_join] y [Unión de aplicación][apply_join].En el caso de las consultas que son esenciales para tu carga de trabajo, especifica el método de unión y el orden de unión más eficientes en tus sentencias de SQL para obtener un rendimiento más coherente.
Optimiza las consultas con la aplicación de predicados de marca de tiempo
La reducción de predicados de marca de tiempo es una técnica de optimización de consultas que se usa en Spanner para mejorar la eficiencia de las consultas que usan marcas de tiempo y datos con una política de almacenamiento por niveles basada en la antigüedad. Cuando habilitas esta optimización, las operaciones de filtrado en las columnas de marca de tiempo se realizan lo antes posible en el plan de ejecución de la consulta. Esto puede reducir de forma significativa la cantidad de datos que se procesan y mejorar el rendimiento general de las consultas.
Con la aplicación de predicados de marca de tiempo, el motor de base de datos analiza la consulta y identifica el filtro de marca de tiempo. Luego, "envía" este filtro a la capa de almacenamiento, de modo que solo se lean de la SSD los datos relevantes según los criterios de marca de tiempo. Esto minimiza la cantidad de datos que se procesan y transfieren, lo que genera una ejecución de consultas más rápida.
Para optimizar las consultas de modo que solo accedan a los datos almacenados en la SSD, se debe aplicar lo siguiente:
- La consulta debe tener habilitada la aplicación de predicados de marca de tiempo. Para obtener más información, consulta Sugerencias de instrucciones de GoogleSQL y Sugerencias de instrucciones de PostgreSQL
La consulta debe usar una restricción basada en la edad igual o menor que la edad especificada en la política de derrame de los datos (establecida con la opción
ssd_to_hdd_spill_timespanen la sentencia de DDLCREATE LOCALITY GROUPoALTER LOCALITY GROUP). Para obtener más información, consulta las sentencias de GoogleSQLLOCALITY GROUPy las sentencias de PostgreSQLLOCALITY GROUP.La columna que se filtra en la consulta debe ser una columna de marca de tiempo que contenga la marca de tiempo de confirmación. Para obtener detalles sobre cómo crear una columna de marca de tiempo de confirmación, consulta Marcas de tiempo de confirmación en GoogleSQL y Marcas de tiempo de confirmación en PostgreSQL. Estas columnas deben actualizarse junto con la columna de marca de tiempo y residir dentro del mismo grupo de localidad, que tiene una política de almacenamiento en niveles basada en la antigüedad.
Si, para una fila determinada, algunas de las columnas que se consultan residen en SSD y otras en HDD (debido a que las columnas se actualizan en momentos diferentes y se trasladan a HDD en momentos diferentes), el rendimiento de la consulta podría ser peor cuando usas la sugerencia. Esto se debe a que la consulta debe completar los datos de las diferentes capas de almacenamiento. Como resultado de usar la sugerencia, Spanner envejece los datos a nivel de celda individual (nivel de detalle de fila y columna) según la marca de tiempo de confirmación de cada celda, lo que ralentiza la consulta. Para evitar este problema, asegúrate de actualizar de forma rutinaria todas las columnas que se consultan con esta técnica de optimización en la misma transacción, de modo que todas las columnas compartan la misma marca de tiempo de confirmación y se beneficien de la optimización.
Para habilitar la aplicación de predicados de marca de tiempo a nivel de la sentencia, usa una sugerencia de sentencia en tu consulta. Por ejemplo:
GoogleSQL
@{allow_timestamp_predicate_pushdown=TRUE}
SELECT s.SingerInfo
FROM Singers s
WHERE s.ModificationTime > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR);
PostgreSQL
/*@allow_timestamp_predicate_pushdown=TRUE*/
SELECT s.SingerInfo
FROM Singers s
WHERE s.ModificationTime > CURRENT_TIMESTAMP - INTERVAL '12 hours';
Evita lecturas extensas en las transacciones de lectura y escritura
Las transacciones de lectura y escritura permiten una secuencia de cero o más lecturas o consultas en SQL, y pueden incluir un conjunto de mutaciones antes de una llamada para confirmar. Para mantener la coherencia de tus datos, Spanner adquiere bloqueos cuando lee y escribe filas en tus tablas y tus índices. Para obtener más información sobre el bloqueo, consulta Vida de las lecturas y escrituras.
Debido a la forma en que funciona el bloqueo en Spanner, realizar una lectura o
una consulta en SQL que lea una gran cantidad de filas (por ejemplo, SELECT * FROM
Singers) significa que ninguna otra transacción puede escribir en las filas que
leíste hasta que se confirme o se anule la transacción.
Además, debido a que tu transacción procesa una gran cantidad de filas, es probable que tarde más que una transacción que lee un rango de filas mucho más pequeño (por ejemplo, SELECT LastName FROM Singers WHERE SingerId = 7), lo que agrava aún más el problema y reduce la capacidad de procesamiento del sistema.
Por lo tanto, intenta evitar las lecturas grandes (por ejemplo, análisis de tablas completas o uniones masivas) en tus transacciones, a menos que estés dispuesto a aceptar una capacidad de procesamiento de escritura más baja.
En algunos casos, el siguiente patrón puede producir mejores resultados:
- Realiza las operaciones de lectura grandes dentro de una transacción de solo lectura. Las transacciones de solo lectura permiten una mayor capacidad de procesamiento agregada porque no usan bloqueos.
- Opcional: Realiza cualquier procesamiento necesario en los datos que acabas de leer.
- Inicia una transacción de lectura y escritura.
- Verifica que las filas críticas no hayan cambiado de valor desde que realizaste
la transacción de solo lectura en el paso 1.
- Si las filas cambiaron, revierte la transacción y comienza de nuevo en el paso 1.
- Si todo sale bien, confirma tus mutaciones.
Una forma de asegurarte de evitar las lecturas grandes en las transacciones de lectura y escritura es observar los planes de ejecución que generan tus consultas.
Usa la cláusula ORDER BY para garantizar el orden de tus resultados de SQL
Si esperas un orden determinado para los resultados de una consulta SELECT,
incluye de forma explícita la cláusula ORDER BY. Por ejemplo, si deseas enumerar todos los cantantes en orden de clave primaria, usa esta consulta:
SELECT * FROM Singers
ORDER BY SingerId;
Spanner garantiza el orden de los resultados solo si la cláusula ORDER BY
está presente en la consulta. En otras palabras, considera esta consulta sin ORDER
BY:
SELECT * FROM Singers;
Spanner no garantiza que los resultados de esta consulta estén
en el orden de la clave primaria. Además, el orden de los resultados puede cambiar en cualquier momento y no se garantiza que sea coherente de una invocación a otra. Si una
consulta tiene una cláusula ORDER BY y Spanner usa un índice que
proporciona el orden requerido, Spanner no ordena los datos de forma
explícita. Por lo tanto, no te preocupes por el impacto en el rendimiento que puede tener incluir esta cláusula. Para verificar si se incluye una operación de ordenamiento explícita en la
ejecución, consulta el plan de consulta.
Usa STARTS_WITH en lugar de LIKE
Debido a que Spanner no evalúa los patrones LIKE parametrizados
hasta el momento de la ejecución, Spanner debe leer todas las filas y evaluarlas
en función de la expresión LIKE para filtrar las filas que no coinciden.
Cuando un patrón LIKE tiene el formato foo% (por ejemplo, comienza con una cadena fija y termina con un solo porcentaje de comodín) y la columna está indexada, usa STARTS_WITH en lugar de LIKE. Esta opción permite que Spanner optimice
el plan de ejecución de consultas de manera más eficaz.
No se recomienda lo siguiente:
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;
Recomendado:
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);
Usa marcas de tiempo de confirmación
Si tu aplicación necesita consultar datos escritos después de un momento determinado, agrega
columnas de marca de tiempo de confirmación a las tablas relevantes. Las marcas de tiempo de confirmación habilitan una
optimización de Spanner que puede reducir la E/S de las consultas cuyas
cláusulas WHERE restringen los resultados a las filas escritas más recientemente que un
momento específico.
Obtén más información sobre esta optimización con bases de datos de dialecto de GoogleSQL o con bases de datos de dialecto de PostgreSQL.