Operadores de ejecución de consultas

Introducción

En esta página, se describen los detalles de los operadores usados en los planes de ejecución de consultas de Cloud Spanner. Si quieres obtener información sobre cómo recuperar un plan de ejecución para una consulta específica con Cloud Console, consulta la sección sobre cómo ejecuta Cloud Spanner las consultas.

Las consultas y los planes de ejecución en esta página se basan en el siguiente esquema de base de datos:

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

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

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget);

CREATE TABLE Songs (
  SingerId  INT64 NOT NULL,
  AlbumId   INT64 NOT NULL,
  TrackId   INT64 NOT NULL,
  SongName  STRING(MAX),
  Duration  INT64,
  SongGenre STRING(25),
) PRIMARY KEY(SingerId, AlbumId, TrackId),
  INTERLEAVE IN PARENT Albums ON DELETE CASCADE;

CREATE INDEX SongsBySingerAlbumSongNameDesc ON Songs(SingerId, AlbumId, SongName DESC), INTERLEAVE IN Albums;

CREATE INDEX SongsBySongName ON Songs(SongName);

CREATE TABLE Concerts (
  VenueId      INT64 NOT NULL,
  SingerId     INT64 NOT NULL,
  ConcertDate  DATE NOT NULL,
  BeginTime    TIMESTAMP,
  EndTime      TIMESTAMP,
  TicketPrices ARRAY<INT64>,
) PRIMARY KEY(VenueId, SingerId, ConcertDate);

Puedes usar las siguientes declaraciones del lenguaje de manipulación de datos (DML) para agregar datos a estas tablas:

INSERT INTO Singers (SingerId, FirstName, LastName, BirthDate)
    VALUES (1, "Marc", "Richards", "1970-09-03"),
           (2, "Catalina", "Smith", "1990-08-17"),
           (3, "Alice", "Trentor", "1991-10-02"),
           (4, "Lea", "Martin", "1991-11-09"),
           (5, "David", "Lomond", "1977-01-29");

    INSERT INTO Albums (SingerId, AlbumId, AlbumTitle)
    VALUES (1, 1, "Total Junk"),
           (1, 2, "Go, Go, Go"),
           (2, 1, "Green"),
           (2, 2, "Forever Hold Your Peace"),
           (2, 3, "Terrified"),
           (3, 1, "Nothing To Do With Me"),
           (4, 1, "Play");

    INSERT INTO Songs (SingerId, AlbumId, TrackId, SongName, Duration, SongGenre)
    VALUES (2, 1, 1, "Let's Get Back Together", 182, "COUNTRY"),
           (2, 1, 2, "Starting Again", 156, "ROCK"),
           (2, 1, 3, "I Knew You Were Magic", 294, "BLUES"),
           (2, 1, 4, "42", 185, "CLASSICAL"),
           (2, 1, 5, "Blue", 238, "BLUES"),
           (2, 1, 6, "Nothing Is The Same", 303, "BLUES"),
           (2, 1, 7, "The Second Time", 255, "ROCK"),
           (2, 3, 1, "Fight Story", 194, "ROCK"),
           (3, 1, 1, "Not About The Guitar", 278, "BLUES");
    

Operadores de hoja

Un operador de hoja es aquel que no tiene operadores secundarios. Los tipos de operadores de hoja son:

Arreglo unnest

Un operador de arreglo unnest compacta el arreglo de entrada en filas de elementos. Cada fila resultante contiene hasta dos columnas: el valor real del arreglo y, opcional, la posición basada en cero en el arreglo.

Por ejemplo:

SELECT a, b FROM UNNEST([1,2,3]) a WITH OFFSET b;
    

La consulta aplana el arreglo [1,2,3] en la columna a y muestra su posición en la columna b.

Estos son los resultados:

a b
1 0
2 1
3 2

Este es el plan de ejecución:

Operador de arreglo unnest

Relación de generación

Un operador de relación de generación muestra cero o más filas.

Relación de unidad

La relación de unidad muestra una fila. Es un caso especial del operador de relación de generación.

Por ejemplo:

SELECT 1 + 2 AS Result;
    

El resultado es:

Result
3

Este es el plan de ejecución:

operador de relación de unidad

Relación vacía

La relación vacía no muestra filas. Es un caso especial del operador de relación de generación.

Por ejemplo:

SELECT * FROM Albums LIMIT 0
    

El resultado es:

No results
    

Este es el plan de ejecución:

operador de relación vacía

Análisis

Un operador de análisis muestra filas mediante el análisis de una fuente de filas. Estos son los tipos de operadores de análisis:

  • Análisis de la tabla: El análisis se realiza en una tabla.
  • Análisis del índice: El análisis se realiza en un índice.
  • Análisis por lotes: El análisis se realiza en tablas intermedias creadas por otros operadores relacionales (por ejemplo, una tabla creada por una aplicación distribuida cruzada).

Siempre que sea posible, Cloud Spanner aplica predicados simples en claves como parte del análisis. Los análisis se ejecutan de manera más eficaz cuando se aplican predicados porque el análisis no necesita leer toda la tabla o el índice. Los predicados aparecen en el plan de ejecución en el formato KeyPredicate: column=value.

Por ejemplo:

SELECT s.LastName
    FROM singers@{FORCE_INDEX=SingersByFirstLastName} AS s
    WHERE s.FirstName = 'Catalina';
    

Estos son los resultados:

LastName
Smith

Este es el plan de ejecución:

operador de análisis

En el plan de ejecución, el operador principal de unión distribuida envía planes secundarios a servidores remotos. Cada subplan tiene un operador de serialización de resultados y un operador de análisis de índice. El predicado Key Predicate: FirstName = 'Catalina' restringe el análisis a las filas del índice SingersByFirstLastname en las que FirstName es igual a Catalina. El resultado del análisis de índice se muestra al operador de serialización de resultados.

Operadores unarios

Un operador unario es el operador que tiene un solo operador secundario relacional.

Los siguientes son operadores unarios:

Total

Un operador de agregación implementa instrucciones de SQL y funciones de agregación GROUP BY(como COUNT). La entrada de un operador de agregación está particionada de manera lógica en grupos organizados en columnas de claves (o en un solo grupo si GROUP BY no está presente). Para cada grupo, se procesan cero o más agregaciones.

Por ejemplo:

SELECT s.SingerId, AVG(s.duration) AS average, COUNT(*) AS count
    FROM Songs AS s
    GROUP BY SingerId;
    

La consulta agrupa por SingerId y realiza una agregación AVG y una agregación COUNT.

Estos son los resultados:

SingerId average count
3 278 1
2 225,875 8

Este es el plan de ejecución:

operador de agregación

Los operadores de agregación pueden estar basados en hash o basados en el flujo. En el plan de ejecución anterior se muestra una agregación basada en transmisiones. Las transmisiones leen de entradas previamente ordenadas (si GROUP BY está presente) y procesan los grupos sin bloquearlos. Las agregaciones basadas en hash compilan tablas hash para mantener las agregaciones incrementales de varias filas de entrada de forma simultánea. Las agregaciones basadas en transmisiones son más rápidas y usan menos memoria que las agregaciones basadas en hash, pero requieren que la entrada se ordene (ya sea en columnas de claves o en índices secundarios).

Para situaciones distribuidas, un operador total se puede separar en un par local/global. Cada servidor remoto realiza la agregación local en sus filas de entrada y, luego, muestra los resultados en el servidor raíz. El servidor raíz realiza la agregación global.

Aplicación de mutaciones

Un operador de aplicación de mutaciones envía las mutaciones de una Declaración de lenguaje de manipulación de datos (DML) a la tabla. Es el operador principal en un plan de consulta para una declaración DML.

Por ejemplo:

DELETE FROM Singers
    WHERE FirstName = 'Alice';
    

Estos son los resultados:

4 rows deleted
    This statement deleted 4 rows and did not return any rows.
    

Este es el plan de ejecución:

aplicación del operador de mutaciones

Creación por lotes

Un operador de creación por lotes agrupa por lotes sus filas de entrada en una secuencia. Por lo general, la operación se realiza como parte de una aplicación distribuida cruzada. Las filas de entrada se pueden volver a ordenar durante la agrupación por lotes. La cantidad de filas de entrada que se agrupan por lotes en cada ejecución del operador de lotes puede variar.

Consulta al operador de aplicación distribuida cruzada para ver un ejemplo de un operador de creación por lotes en un plan de ejecución.

Compute

Un operador de procesamiento produce resultados mediante la lectura de las filas de entrada y el agregado de una o más columnas adicionales que se procesan mediante expresiones escalares. Consulta el operador unir todo para ver un ejemplo del operador de procesamiento en un plan de ejecución.

Estructura de procesamiento

Un operador de estructura de procesamiento crea una variable para una estructura que contiene campos destinados a cada una de las columnas de entrada.

Por ejemplo:

SELECT FirstName,
           ARRAY(SELECT AS STRUCT song.SongName, song.SongGenre
                 FROM Songs AS song
                 WHERE song.SingerId = singer.SingerId)
    FROM singers AS singer
    WHERE singer.SingerId = 3;
    

Estos son los resultados:

FirstName Unspecified
Alice [["Not About the Guitar","BLUES"]]

Este es el plan de ejecución:

operador de estructura de procesamiento

En el plan de ejecución, el operador de subconsulta del arreglo recibe la entrada desde un operador de unión distribuida, el cual recibe la entrada desde un operador de estructura de procesamiento. El operador de estructura de procesamiento crea una estructura a partir de las columnas SongName y SongGenre en la tabla Songs.

Filtro

Un operador de filtro lee todas las filas de su entrada, aplica un predicado escalar en cada una y, luego, solo muestra las filas que satisfacen el predicado.

Por ejemplo:

SELECT s.LastName FROM (SELECT s.LastName
    FROM Singers AS s LIMIT 3) s
    WHERE s.LastName LIKE 'Rich%';
    

Estos son los resultados:

LastName
Richards

Este es el plan de ejecución:

operador de filtro

El predicado para cantantes cuyo apellido comienza con Rich se implementa como un filtro. La entrada del filtro es el resultado de un análisis de índice, y el resultado del filtro son las filas en las que LastName comienza con Rich.

Para el rendimiento, el filtro influye en la forma en que se leen los datos cada vez que uno se coloca directamente sobre un análisis. Por ejemplo, considera una tabla con la clave k. Un filtro con predicado k = 5 directamente por sobre un análisis de la tabla buscará filas que coincidan con k = 5, sin leer toda la entrada. Esto da como resultado una ejecución más eficiente de la consulta. En el ejemplo anterior, el operador de filtro solo lee las filas que satisfacen el predicado WHERE s.LastName LIKE 'Rich%'.

Análisis de filtro

Un operador de análisis de filtro siempre se encuentra por sobre un análisis de tabla o índice. Funciona junto con el análisis para reducir la cantidad de filas leídas de la base de datos, y el resultado suele ser más rápido que con un filtro. Cloud Spanner aplica el análisis de filtro en ciertas condiciones:

  • Condición de búsqueda: Esta condición se aplica si Cloud Spanner puede determinar una fila específica para acceder en la tabla. En general, esto sucede cuando el filtro está en un prefijo de la clave primaria. Por ejemplo, si la clave primaria está formada por Col1 y Col2, entonces se puede buscar una cláusula WHERE que incluya valores explícitos para Col1, o Col1 y Col2. En ese caso, Cloud Spanner solo lee datos dentro del rango de claves.
  • Condición residual: Cualquier otra condición en la que Cloud Spanner puede evaluar el análisis para limitar la cantidad de datos que se leen.

Por ejemplo:

SELECT LastName
    FROM Singers
    WHERE SingerId = 1
    

Estos son los resultados:

LastName
Richards

Este es el plan de ejecución:

operador de análisis de filtro

Límite

Un operador de límite restringe la cantidad de filas que se muestran. El parámetro OFFSET opcional especifica la fila de inicio que se muestra. Para las situaciones distribuidas, un operador de límite se puede separar en un par local/global. Cada servidor remoto aplica el límite local para las filas de salida y, luego, muestra los resultados en el servidor raíz. El servidor raíz agrega las filas enviadas por los servidores remotos y, luego, aplica el límite global.

Por ejemplo:

SELECT s.SongName
    FROM Songs AS s
    LIMIT 3;
    

Estos son los resultados:

SongName
Not About The Guitar
The Second Time
Starting Again

Este es el plan de ejecución:

operador límite

El límite local es el límite para cada servidor remoto. El servidor raíz agrega las filas de los servidores remotos y, luego, aplica el límite global.

Sample

Un operador de muestra devuelve un subconjunto de su entrada en función de un muestreo de filas de entrada. Los métodos de muestreo compatibles son Bernoulli y Reservoir.

Por ejemplo:

SELECT s.SongName
    FROM Songs AS s TABLESAMPLE BERNOULLI (10 PERCENT);
    

La consulta usa el muestreo de Bernoulli con una tasa de muestreo del 10%.

Estos son los resultados:

SongName
Starting Again
Nothing Is The Same

Ten en cuenta que dado que el resultado es una muestra, puede variar cada vez que la consulta se ejecute, aunque sea la misma.

Este es el plan de ejecución:

operador de muestra

En este plan de ejecución, el operador de muestra recibe la entrada desde un operador de unión distribuida, el cual recibe la entrada desde un análisis del índice. Un operador de muestra presenta sus filas de muestra al operador de serialización de resultados.

Serialización de resultados

Un operador de serialización de resultados es un caso especial del operador de estructura de procesamiento que serializa cada fila del resultado final de la consulta para mostrarla al cliente.

Por ejemplo:

SELECT ARRAY(SELECT AS STRUCT so.SongName, so.SongGenre
                 FROM Songs AS so
                 WHERE so.SingerId = s.SingerId)
    FROM Singers AS s;
    

La consulta solicita un arreglo de SongName y SongGenre en función de SingerId.

Estos son los resultados:

Unspecified
[]
[[Let's Get Back Together, COUNTRY], [Starting Again, ROCK]]
[[Not About The Guitar, BLUES]]
[]
[]

Este es el plan de ejecución:

Operador de serialización de resultados

El operador de serialización de resultados crea un resultado que contiene SongName y SongGenre para cada fila de la tabla Songs.

Orden

Un operador de orden lee las filas de entrada, las organiza por columnas y, luego, muestra los resultados ordenados.

Por ejemplo:

SELECT s.SongGenre
    FROM Songs AS s
    ORDER By SongGenre;
    

Estos son los resultados:

SongGenre
BLUES
BLUES
BLUES
BLUES
CLASSICAL
COUNTRY
ROCK
ROCK
ROCK

Este es el plan de ejecución:

operador de orden

En este plan de ejecución, el operador de orden recibe las filas de entrada desde un operador de unión distribuida, ordena las filas de entrada y muestra las filas ordenadas al operador de resultado de serialización.

A fin de limitar la cantidad de filas que se muestran, un operador de orden puede tener los parámetros LIMIT y OFFSET como opción. Para situaciones distribuidas, un operador de ordenamiento con un operador LIMIT o OFFSET se divide en un par local/global. Cada servidor remoto aplica el orden de clasificación y el límite/desplazamiento local para sus filas de entrada y, luego, muestra los resultados en el servidor raíz. El servidor raíz agrega las filas enviadas por los servidores remotos, las ordena y, luego, aplica el límite/desplazamiento global.

Por ejemplo:

SELECT s.SongGenre
    FROM Songs AS s
    ORDER By SongGenre
    LIMIT 3;
    

Estos son los resultados:

SongGenre
BLUES
BLUES
BLUES

Este es el plan de ejecución:

operador de orden con límites

En el plan de ejecución se muestra el límite local para los servidores remotos y el límite global para el servidor raíz.

Entrada de la unión

Un operador de entrada de la unión le muestra los resultados al operador unir todo. Consulta el operador unir todo para ver un ejemplo del operador de entrada de unión en un plan de ejecución.

Operadores binarios

Un operador binario es el que tiene dos operadores secundarios relacionales. Los siguientes son operadores binarios:

Aplicación cruzada

Un operador de aplicación cruzada ejecuta una consulta de tabla en cada fila recuperada por una consulta de otra tabla y muestra la unión de todas las ejecuciones de consulta de tabla. Los operadores de aplicación cruzada y de aplicación externa realizan el procesamiento orientado a filas, a diferencia de los operadores que ejecutan el procesamiento basado en conjuntos, como unión hash. El operador de aplicación cruzada tiene dos entradas, entrada y mapa. Dicho operador aplica cada fila del lado de entrada al lado del mapa. El resultado de la aplicación contiene columnas de los lados de entrada y mapa.

Por ejemplo:

SELECT si.FirstName,
      (SELECT so.SongName
       FROM Songs AS so
       WHERE so.SingerId=si.SingerId
       LIMIT 1)
    FROM Singers AS si;
    

La consulta solicita el nombre de cada cantante, junto con el nombre de solo una de sus canciones.

Estos son los resultados:

FirstName Unspecified
Alice Not About The Guitar
Catalina Let's Get Back Together
David NULL
Lea NULL
Marc NULL

La primera columna se propaga desde la tabla Singers y la segunda columna lo hace desde la tabla Songs. En los casos en que haya un SingerId en la tabla Singers pero no haya coincidencias de SingerId en la tabla Songs, la segunda columna contendrá NULL.

Este es el plan de ejecución:

operador de aplicación cruzada

El nodo de nivel superior es un operador de unión distribuida. El operador de unión distribuida reparte los planes secundarios a los servidores remotos. El subplan contiene un operador de serialización de resultados que procesa el nombre del cantante y el nombre de una de sus canciones, y serializa cada fila del resultado.

El operador de serialización de resultados recibe su entrada desde el operador de aplicación cruzada. El lado de entrada para el operador de aplicación cruzada es un análisis de tabla en la tabla Singers.

El lado del mapa de la operación de aplicación cruzada contiene lo siguiente (de arriba abajo):

  • Un operador de agregación que muestra Songs.SongName.
  • Un operador de límite que restringe la cantidad de canciones que se muestran a una por cantante.
  • Un análisis de índice en el índice SongsBySingerAlbumSongNameDesc.

El operador de aplicación cruzada asigna cada fila desde el lado de entrada a una fila en el lado del mapa que tiene el mismo SingerId. El resultado del operador de aplicación cruzada es el valor FirstName desde la fila de entrada y el valor SongName desde la fila del mapa. (El valor SongName será NULL si no hay ninguna fila del mapa que coincida con el SingerId). El operador de unión distribuida en la parte superior del plan de ejecución combina todas las filas de salida de los servidores remotos y los muestra como resultados de la consulta.

Unión hash

Un operador de unión hash es una implementación basada en hash de uniones de SQL. Las uniones de hash ejecutan el procesamiento basado en conjuntos. El operador de unión hash lee las filas de la entrada marcadas como compilación y las inserta en una tabla hash basada en una condición de unión. Luego, lee las filas de la entrada marcadas como sondeo. Para cada fila que se lee desde la entrada de sondeo, el operador busca las filas que coinciden en la tabla hash y las muestra como resultado.

Por ejemplo:

SELECT a.AlbumTitle, s.SongName
    FROM Albums AS a HASH JOIN Songs AS s
    ON a.SingerId = s.SingerId AND a.AlbumId = s.AlbumId;
    

Estos son los resultados:

AlbumTitle SongName
Nothing To Do With Me Not About The Guitar
Green The Second Time
Green Starting Again
Green Nothing Is The Same
Green Let's Get Back Together
Green I Knew You Were Magic
Green Blue
Green 42
Terrified Fight Story

Este es el plan de ejecución:

operador de unión hash

En el plan de ejecución, compilación es una unión distribuida que reparte los análisis en la tabla Albums. Sondeo es un operador de unión distribuida que reparte los análisis en el índice SongsBySingerAlbumSongNameDesc. El operador de unión hash lee todas las filas desde el lado de la compilación. Cada fila de compilación se coloca en una tabla hash basada en las columnas de la condición a.SingerId = s.SingerId AND a.AlbumId = s.AlbumId. A continuación, el operador de unión hash lee todas las filas del lado del sondeo. Para cada fila de sondeo, el operador de unión hash busca coincidencias en la tabla hash. El operador de unión hash muestra las coincidencias resultantes.

En la tabla hash, estas también se pueden filtrar por una condición residual antes de que se muestren. (Un ejemplo de dónde aparecen las condiciones residuales es en las uniones que no son de igualdad). Los planes de ejecución de unión hash pueden ser complejos debido a la administración de memoria y a las variantes de unión. El algoritmo principal de unión hash está adaptado para manejar variantes de unión interna, semi, anti y externa.

Aplicación externa

Un operador de aplicación externa es similar a un operador de aplicación cruzada, excepto que, de ser necesario, el operador de aplicación externa crea una fila rellena con el valor NULL para garantizar que cada ejecución en el lado del mapa muestre al menos una fila. (En otras palabras, proporciona una semántica de combinación externa izquierda).

Operadores N-arios

Un operador N-ario es el que tiene más de dos operadores secundarios relacionales. Los siguientes son operadores N-arios:

Unir todo

Un operador unir todo combina todos los conjuntos de filas de sus operadores secundarios sin quitar los duplicados. Los operadores unir todo reciben sus entradas de operadores de entrada de la unión que se distribuyen en varios servidores. El operador unir todo requiere que sus entradas tengan el mismo esquema, es decir, el mismo conjunto de tipos de datos para cada columna.

Por ejemplo:

SELECT 1 a, 2 b
    UNION ALL
    SELECT 3 a, 4 b
    UNION ALL
    SELECT 5 a, 6 b;
    

El tipo de fila para los operadores secundarios consta de dos números enteros.

Estos son los resultados:

a b
1 2
3 4
5 6

Este es el plan de ejecución:

operador_union_all

El operador unir todo combina sus filas de entrada y, en este ejemplo, envía los resultados al operador de serialización de resultados.

Una consulta como la siguiente funcionaría correctamente porque se usa el mismo conjunto de tipos de datos para cada columna, aunque los operadores secundarios usen variables diferentes para los nombres de las columnas:

SELECT 1 a, 2 b
    UNION ALL
    SELECT 3 c, 4 e;
    

Una consulta como la siguiente no tendría éxito porque los operadores secundarios usan tipos de datos diferentes para las columnas:

SELECT 1 a, 2 b
    UNION ALL
    SELECT 3 a, 'This is a string' b;
    

Subconsultas escalares

Una subconsulta escalar es una subexpresión de SQL que es parte de una expresión escalar. Cloud Spanner intenta quitar las subconsultas escalares siempre que sea posible. Sin embargo, en algunos casos, los planes pueden contener subconsultas escalares de manera explícita.

Por ejemplo:

SELECT FirstName,
    IF(FirstName='Alice',
       (SELECT COUNT(*)
        FROM Songs
        WHERE Duration > 300),
       0)
    FROM Singers;
    

Esta es la subexpresión de SQL:

SELECT COUNT(*)
    FROM Songs
    WHERE Duration > 300;
    

Estos son los resultados (de la consulta completa):

FirstName
Alice 1
Catalina 0
David 0
Lea 0
Marc 0

Este es el plan de ejecución:

operador de subconsulta escalar

El plan de ejecución contiene una subconsulta escalar, que se muestra como Subconsulta escalar, sobre un operador de agregación.

A veces, a fin de mejorar el rendimiento, Cloud Spanner convierte las subconsultas escalares en otro operador, como una unión o una aplicación cruzada.

Por ejemplo:

SELECT *
    FROM Songs
    WHERE Duration = (SELECT MAX(Duration) FROM Songs);
    

Esta es la subexpresión de SQL:

SELECT MAX(Duration) FROM Songs;
    

Estos son los resultados (de la consulta completa):

SingerId AlbumId TrackId SongName Duration SongGenre
2 1 6 Nothing Is The Same 303 BLUES

Este es el plan de ejecución:

El operador de subconsulta escalar no se muestra en el plan

El plan de ejecución no contiene una subconsulta escalar porque Cloud Spanner la convirtió en una aplicación cruzada.

Subconsultas de arreglos

La subconsulta de arreglos es similar a una subconsulta escalar, excepto que se le permite a la subconsulta poder consumir más de una fila de entrada. Las filas consumidas se convierten en un único arreglo de salida escalar que contiene un elemento por cada fila de entrada consumida.

Por ejemplo:

SELECT a.AlbumId,
    ARRAY(SELECT ConcertDate
          FROM Concerts
          WHERE Concerts.SingerId = a.SingerId)
    FROM Albums AS a;
    

Esta es la subconsulta:

SELECT ConcertDate
    FROM Concerts
    WHERE Concerts.SingerId = a.SingerId;
    

Los resultados de la subconsulta para cada AlbumId se convierten en un arreglo de filas de ConcertDate en comparación con las de AlbumId. El plan de ejecución contiene una subconsulta de arreglo, que se muestra como Subconsulta de arreglo, por encima de un operador de unión distribuida:

operador de subconsulta de arreglos

Operadores distribuidos

Los operadores antes descritos en esta página se ejecutan dentro de los límites de una sola máquina. Los operadores distribuidos se ejecutan en varios servidores.

Los siguientes son operadores distribuidos:

Un operador de unión distribuida es el operador básico a partir del cual se derivan las aplicaciones distribuidas cruzadas y las aplicaciones distribuidas externas.

Los operadores distribuidos aparecen en los planes de ejecución con una variante de unión distribuida sobre una o más variantes de unión distribuida local. Una variante de unión distribuida realiza la distribución remota de los subplanes. Una variante de unión distribuida local se encuentra encima de cada uno de los análisis realizados para la consulta, como se muestra en este plan de ejecución:

operador distribuido

Las variantes de unión distribuida local garantizan la ejecución estable de consultas cuando se producen reinicios para los límites de división que cambian de forma dinámica.

Siempre que sea posible, una variante de unión distribuida tiene un predicado dividido que da como resultado una depuración dividida; es decir, los servidores remotos ejecutan subplanes solo en las divisiones que satisfacen el predicado. Esto mejora la latencia y el rendimiento general de las consultas.

Unión distribuida

Un operador de unión distribuida divide de manera conceptual una o más tablas en varias divisiones, evalúa una subconsulta de manera independiente en cada división y, luego, unifica todos los resultados.

Por ejemplo:

SELECT s.SongName, s.SongGenre
    FROM Songs AS s
    WHERE s.SingerId = 2 AND s.SongGenre = 'ROCK';
    

Estos son los resultados:

SongName SongGenre
Starting Again ROCK
The Second Time ROCK
Fight Story ROCK

Este es el plan de ejecución:

operador de unión distribuida

Un operador de unión distribuida envía planes secundarios a servidores remotos, que realizan un análisis de tabla en divisiones que satisfacen el predicado WHERE s.SingerId = 2 AND s.SongGenre = 'ROCK' de la consulta. Un operador de serialización de resultados procesa los valores de SongName y SongGenre desde las filas que muestran los análisis de tabla. Luego, el operador de unión distribuida muestra los resultados combinados de los servidores remotos como los resultados de la consulta de SQL.

Aplicación distribuida cruzada

Un operador de aplicación distribuida cruzada (DCA) extiende el operador de aplicación cruzada mediante la ejecución en varios servidores. El lado de entrada del DCA agrupa los lotes de filas (a diferencia de un operador de aplicación cruzada normal, que actúa solo en una fila de entrada a la vez). El lado del mapa del DCA es un conjunto de operadores de aplicación cruzada que se ejecutan en servidores remotos.

Por ejemplo:

SELECT AlbumTitle FROM Songs
    JOIN Albums ON Albums.AlbumId=Songs.AlbumId;
    

Los resultados están en el formato:

AlbumTitle
Green
Nothing To Do With Me
Play
Total Junk
Green

Este es el plan de ejecución:

operador de aplicación distribuida cruzada

La entrada de DCA contiene un análisis del índice en la tabla Albums que agrupa filas de datos de AlbumId y SingerId. El lado del mapa de este operador de aplicación cruzada es un análisis de índice en el índice SongsBySingerAlbumSongNameDesc, sujeto al predicado de SingerId en la fila de entrada que coincide con la clave SingerId en el índice SongsBySingerAlbumSongNameDesc. La asignación muestra el SongName para los valores SingerId en las filas de entrada por lotes.

Para resumir el proceso del DCA de este ejemplo, la entrada de la DCA son las filas por lotes de la tabla Albums y el resultado de la DCA es la aplicación de estas filas al mapa del análisis del índice.

Aplicación distribuida externa

Un operador de aplicación distribuida externa extiende el operador de aplicación externa mediante la ejecución de varios servidores, similar a la forma en que un operador de aplicación cruzada distribuida extiende a un operador de aplicación cruzada.

Por ejemplo:

SELECT AlbumTitle FROM Songs
    LEFT OUTER JOIN@{JOIN_TYPE=APPLY_JOIN} Albums
    ON Albums.AlbumId=Songs.AlbumId;
    

Los resultados están en el formato:

AlbumTitle
Green
Nothing To Do With Me
Play
Total Junk
Green

Este es el plan de ejecución:

operador de aplicación externa distribuida

Información adicional

En esta sección, se describen los elementos que no son operadores independientes, sino que ejecutan tareas para asistir a uno o más de los operadores que se mencionaron antes. Los elementos que se describen aquí son técnicamente operadores, pero no son operadores independientes en tu plan de consultas.

Constructor de estructura

Un constructor de estructura crea una estructura o una colección de campos. Por lo general, crea una estructura para las filas que resultan de una operación de procesamiento. Un constructor de estructura no es un operador independiente. En cambio, aparece en los operadores de estructura de procesamiento o de serialización de resultados.

Para una operación de estructura de procesamiento, el constructor crea una estructura destinada a que las columnas de las filas procesadas puedan usar una sola variable de referencia para la estructura.

Para una operación de serialización de resultados, el constructor de la estructura crea una estructura a fin de serializar los resultados.

Por ejemplo:

SELECT IF(TRUE, struct(1 AS A, 1 AS B), struct(2 AS A , 2 AS B)).A;
    

Estos son los resultados:

A
1

Este es el plan de ejecución:

constructor de estructura

En el plan de ejecución, los constructores de estructuras aparecen dentro de un operador de serialización de resultados.