Constructos de SQL para consultas paralelas en Aurora MySQL - Amazon Aurora

Constructos de SQL para consultas paralelas en Aurora MySQL

En la siguiente sección, puede encontrar información más detallada acerca de por qué determinadas instrucciones de SQL usan o no usan consulta paralela. En esta sección también se detalla cómo interactúan las características de Aurora MySQL con la consulta paralela. Esta información le ayudará a diagnosticar los problemas de rendimiento para un clúster que use consultas paralelas o a comprender cómo se aplican las consultas paralelas a su carga de trabajo concreta.

La decisión de usar consultas en paralelo depende de muchos factores que tienen lugar en el momento en que se ejecuta la instrucción. Por tanto, la consulta en paralelo podría usarse para determinadas consultas siempre, nunca o solo en ciertas condiciones.

sugerencia

Cuando consulte estos ejemplos en HTML, puede utilizar el widget Copy (Copiar) en la esquina superior derecha de cada descripción de código para copiar el código SQL y probarlo usted mismo. El uso del widget Copy (Copiar) evita copiar los caracteres adicionales alrededor de las líneas de solicitud de mysql> y de continuación de ->.

Instrucción EXPLAIN

Como se muestra en los ejemplos de esta sección, la instrucción EXPLAIN indica si cada fase de una consulta es apta actualmente para las consultas en paralelo. También indica qué aspectos de una consulta se pueden bajar a la capa de almacenamiento. Los elementos más importantes del plan de consulta son los siguientes:

  • Un valor distinto de NULL para la columna key indica que la consulta se puede realizar con eficacia usando búsquedas del índice y que es poco probable el uso de consultas en paralelo.

  • Un valor pequeño para la columna rows (un valor que no sea de millones) indica que la consulta no accede a suficientes datos para que valga la pena realizar consultas paralelas. Esto significa que la consulta paralela es poco probable.

  • La columna Extra muestra si se espera usar consultas en paralelo. Este resultado tiene el aspecto del siguiente ejemplo.

    Using parallel query (A columns, B filters, C exprs; D extra)

    El número de columns representa a cuántas columnas se hace referencia en el bloque de consultas.

    El número de filters representa el número de predicados de WHERE que representan una simple comparación de un valor de columna con una constante. La comparación puede ser de igualdad, desigualdad o rango. Aurora puede paralelizar estos tipos de predicados con más eficacia.

    El número de exprs representa el número de expresiones como las llamadas de función, operadores u otras expresiones que también se pueden paralelizar, aunque no con la misma eficacia que una condición de filtro.

    El número extra representa cuántas expresiones no se pueden bajar y las realiza el nodo director.

Por ejemplo, fíjese en el siguiente resultado de EXPLAIN.

mysql> explain select p_name, p_mfgr from part -> where p_brand is not null -> and upper(p_type) is not null -> and round(p_retailprice) is not null; +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+

La información de la columna Extra muestra que se extraen cinco columnas de cada fila para evaluar las condiciones de consulta y construir el conjunto de resultados. Un predicado WHERE implica un filtro, es decir, una columna que se prueba directamente en la cláusula WHERE. Dos cláusulas WHERE requieren la evaluación de expresiones más complicadas, en este caso implican llamadas de función. El campo 0 extra confirma que todas las operaciones de la cláusula WHERE se bajan a la capa de almacenamiento como parte del procesamiento de consultas en paralelo.

En los casos en los que las consultas en paralelo no se eligen, normalmente se puede deducir el motivo de las otras columnas de la salida EXPLAIN. Por ejemplo, el valor de rows podría ser demasiado pequeño o la columna possible_keys podría indicar que la consulta puede usar búsqueda de índice en lugar de un análisis de uso intensivo de datos. En el ejemplo siguiente se muestra una consulta en la que el optimizador puede estimar que la consulta solo analizará un pequeño número de filas. Lo hace en función de las características de la clave principal. En este caso, las consultas en paralelo no se requieren.

mysql> explain select count(*) from part where p_partkey between 1 and 100; +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | 1 | SIMPLE | part | range | PRIMARY | PRIMARY | 4 | NULL | 99 | Using where; Using index | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+

La salida que muestra si se usarán las consultas en paralelo tiene en cuenta todos los factores disponibles en el momento en que se ejecuta la instrucción EXPLAIN. El optimizador podría realizar una elección distinta cuando la consulta se ejecute realmente, si la situación ha cambiado mientras tanto. Por ejemplo, EXPLAIN podría notificar que una instrucción usará consultas en paralelo. Pero cuando la consulta se ejecute realmente más tarde, podría no usar consultas en paralelo en función de las condiciones de ese momento. Estas condiciones pueden incluir otras consultas paralelas que se ejecutan simultáneamente. También pueden incluir filas que se eliminan de la tabla, la creación de un nuevo índice, el paso de demasiado tiempo dentro de una transacción abierta, etc.

Cláusula WHERE

Para que una consulta use la optimización de consultas en paralelo, debe incluir una cláusula WHERE.

La optimización de consultas en paralelo acelera muchos tipos de expresiones usadas en la cláusula:WHERE

  • Comparaciones simples de un valor de columna con una constante, conocidos como filtros. Estas comparaciones se benefician más de bajarse a la capa de almacenamiento. El número de expresiones de filtro de una consulta se notifica en la salida de EXPLAIN.

  • Otros tipos de expresiones de la cláusula WHERE también se bajan a la capa de almacenamiento cuando es posible. El número de expresiones de ese tipo en una consulta se notifica en la salida de EXPLAIN. Dichas expresiones pueden ser llamadas de función, operadores LIKE, expresiones CASE, etc.

  • Determinadas funciones y operadores actualmente no se bajan mediante consultas en paralelo. El número de expresiones de ese tipo en una consulta se notifica como extra en la salida de EXPLAIN. El resto de la consulta puede seguir usando consultas en paralelo.

  • Aunque las expresiones de la lista de selección no se bajan, las consultas que contengan tales funciones siguen pudiendo beneficiarse del tráfico de red reducido por los resultados intermedios de las consultas en paralelo. Por ejemplo, las consultas que llaman a funciones de agregación en la lista de selección pueden beneficiarse de las consultas en paralelo, incluso aunque las funciones de agregación no se bajen.

Por ejemplo, la siguiente consulta realiza un análisis de tabla completa y procesa todos los valores de la columna P_BRAND. Sin embargo, no usa consultas en paralelo porque la consulta no incluye ninguna cláusula WHERE.

mysql> explain select count(*), p_brand from part group by p_brand; +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | 1 | SIMPLE | part | ALL | NULL | NULL | NULL | NULL | 20427936 | Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+

Por el contrario, la siguiente consulta incluye predicados de WHERE que filtran los resultados, de forma que se pueden aplicar las consultas en paralelo:

mysql> explain select count(*), p_brand from part where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 -> group by p_brand; +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using temporary; Using filesort; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+...+----------+-------------------------------------------------------------------------------------------------------------+

Si el optimizador estima que el número de filas devueltas para un bloque de consulta es pequeño, las consultas en paralelo no se usan para ese bloque de consultas. En el siguiente ejemplo se muestra un caso en el que un operador de mayor que de la columna de clave principal se aplica a un millón de filas, lo que causa que se usen las consultas en paralelo. La prueba contraria de menor que se estima que se aplicará solo a unas pocas filas y no usa las consultas en paralelo.

mysql> explain select count(*) from part where p_partkey > 10; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+ mysql> explain select count(*) from part where p_partkey < 10; +----+...+------+--------------------------+ | id |...| rows | Extra | +----+...+------+--------------------------+ | 1 |...| 9 | Using where; Using index | +----+...+------+--------------------------+

Lenguaje de definición de datos (DDL)

En la versión 2 de Aurora MySQL, las consultas en paralelo solo están disponibles para las tablas que no tienen pendientes operaciones de lenguaje de definición de datos (DDL) rápidas. En Aurora MySQL versión 3, puede utilizar una consulta paralela en una tabla al mismo tiempo que una operación DDL instantánea.

El DDL instantáneo en la versión 3 de Aurora MySQL reemplaza a la característica de DDL rápida en la versión 2 de Aurora MySQL. Para obtener información sobre DDL instantáneo, consulte DDL instantáneo (Aurora MySQL versión 3).

Tipos de datos de columna

En Aurora MySQL versión 3, la consulta paralela puede funcionar con tablas que contienen columnas con tipos de datos TEXT, BLOB, JSON, y GEOMETRY. También puede funcionar con las columnas VARCHAR y CHAR con una longitud máxima declarada superior a 768 bytes. Si la consulta hace referencia a cualquier columna que contenga tipos de objetos tan grandes, el trabajo adicional para recuperarlos agrega cierta sobrecarga al procesamiento de consultas. En ese caso, verifique si la consulta puede omitir las referencias a esas columnas. De lo contrario, ejecute puntos de referencia para confirmar si estas consultas son más rápidas con la consulta paralela activada o desactivada.

En la versión 2 de Aurora MySQL, la consulta paralela tiene estas limitaciones para los tipos de objetos grandes:

  • Los tipos de datos TEXT, BLOB, JSON y GEOMETRY no son compatibles con las consultas paralelas. Una consulta que haga referencia a cualquier columna de estos tipos no puede usar consultas en paralelo.

  • Las columnas de longitud variable (tipos de datos VARCHAR y CHAR) son compatibles con las consultas en paralelo hasta una longitud máxima declarada de 768 bytes. Una consulta que haga referencia a cualquier columna de los tipos declarados con una longitud máxima más larga no puede usar consultas en paralelo. En el caso de columnas que usen conjuntos de caracteres multibyte, el límite de bytes tiene en cuenta el número máximo de bytes del conjunto de caracteres. Por ejemplo, para el conjunto de caracteres utf8mb4 (que tiene una longitud máxima de caracteres de 4 bytes), una columna VARCHAR(192) es compatible con una consulta en paralelo, pero una columna VARCHAR(193) no lo es.

Tablas particionadas

Puede utilizar tablas particionadas con consultas en paralelo en Aurora MySQL versión 3. Dado que las tablas particionadas se representan internamente como varias tablas más pequeñas, una consulta que utiliza una consulta paralela en una tabla no particionada podría no utilizar una consulta paralela en una tabla particionada idéntica. Aurora MySQL considera si cada partición es lo suficientemente grande como para calificar para la optimización de consultas paralelas, en lugar de evaluar el tamaño de toda la tabla. Verifique si la variable de estado Aurora_pq_request_not_chosen_small_table se incrementa si una consulta de una tabla particionada no utiliza una consulta paralela cuando se espera que lo haga.

Por ejemplo, considere una tabla particionada con PARTITION BY HASH (column) PARTITIONS 2 y otra tabla particionada con PARTITION BY HASH (column) PARTITIONS 10. En la tabla con dos particiones, las particiones son cinco veces más grandes que la tabla con diez particiones. Por lo tanto, es más probable que las consultas paralelas se utilicen para consultas en la tabla con menos particiones. En el siguiente ejemplo, la tabla PART_BIG_PARTITIONS tiene dos particiones y PART_SMALL_PARTITIONS tiene diez particiones. Con datos idénticos, es más probable que las consultas paralelas se utilicen para la tabla con menos particiones grandes.

mysql> explain select count(*), p_brand from part_big_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | 1 | SIMPLE | part_big_partitions | p0,p1 | Using where; Using temporary; Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra; 1 group-bys, 1 aggrs) | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ mysql> explain select count(*), p_brand from part_small_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+-----------------------+-------------------------------+------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+-----------------------+-------------------------------+------------------------------+ | 1 | SIMPLE | part_small_partitions | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 | Using where; Using temporary | +----+-------------+-----------------------+-------------------------------+------------------------------+

Funciones de agregación, cláusulas GROUP BY y cláusulas HAVING

Las consultas que implican funciones de agregación suelen ser buenas candidatas para las consultas en paralelo porque implican el análisis de números grandes de filas en tablas grandes.

En Aurora MySQL 3, la consulta paralela puede optimizar las llamadas a funciones agregadas en la lista de selección y en la cláusula HAVING.

Antes de la versión 3 de Aurora MySQL, las llamadas de función agregadas en la lista de selección o la cláusula HAVING no se bajan a la capa de almacenamiento. Sin embargo, las consultas en paralelo siguen mejorando el rendimiento de tales consultas con las funciones de agregación. Para ello, primero extraen los valores de columna de las páginas de datos sin procesar en paralelo en la capa de almacenamiento. A continuación, transmiten dichos valores de vuelta al nodo director en formato compacto de tupla en lugar de como páginas de datos completas. Como siempre, la consulta requiere al menos un predicado WHERE para que las consultas en paralelo se activen.

En los siguientes ejemplos simples se ilustran los tipos de consultas de agregación que pueden aprovechar las consultas en paralelo. Para ello, devuelven los resultados intermedios en formato compacto al nodo director, filtran las filas que no coinciden de los resultados intermedios o ambos.

mysql> explain select sql_no_cache count(distinct p_brand) from part where p_mfgr = 'Manufacturer#5'; +----+...+----------------------------------------------------------------------------+ | id |...| Extra | +----+...+----------------------------------------------------------------------------+ | 1 |...| Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------------------------------------------------------------------------+ mysql> explain select sql_no_cache p_mfgr from part where p_retailprice > 1000 group by p_mfgr having count(*) > 100; +----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (3 columns, 0 filters, 1 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+

Llamadas de función en la cláusula WHERE

Aurora puede aplicar la optimización de consultas en paralelo a llamadas a la mayoría de las funciones integradas en la cláusula WHERE. La paralelización de estas llamadas de función descarga algo de trabajo de la CPU del nodo director. La evaluación de las funciones de predicado en paralelo durante la fase inicial de consulta ayuda a Aurora a minimizar la cantidad de datos que se transmiten y procesan durante las fases posteriores.

Actualmente, la paralelización no se aplica a llamadas de función de la lista de selección. Dichas funciones las evalúa el nodo director, incluso aunque aparezca una función idéntica en la cláusula WHERE. Los valores originales de las columnas relevantes se incluyen en las tuplas transmitidas desde los nodos de almacenamiento de vuelta al nodo director. El nodo director realiza las transformaciones, como UPPER, CONCATENATE, etc., para producir los valores finales del conjunto de resultados.

En el siguiente ejemplo, la consulta paralela paraleliza la llamada a LOWER porque aparece en la cláusula WHERE. Las consultas paralelas no afectan a las llamadas a SUBSTR y UPPER porque aparecen en la lista de selección.

mysql> explain select sql_no_cache distinct substr(upper(p_name),1,5) from part -> where lower(p_name) like '%cornflower%' or lower(p_name) like '%goldenrod%'; +----+...+---------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+---------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+...+---------------------------------------------------------------------------------------------+

La misma consideración se aplica a otras expresiones, como las expresiones CASE o los operadores LIKE. Por ejemplo, en el siguiente ejemplo se muestra que las consultas en paralelo evalúan la expresión CASE y los operadores LIKE de la cláusula WHERE.

mysql> explain select p_mfgr, p_retailprice from part -> where p_retailprice > case p_mfgr -> when 'Manufacturer#1' then 1000 -> when 'Manufacturer#2' then 1200 -> else 950 -> end -> and p_name like '%vanilla%' -> group by p_retailprice; +----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (4 columns, 0 filters, 2 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+

Cláusula LIMIT

Actualmente, las consultas en paralelo no se utilizan para ningún bloque de consultas que incluya una cláusula LIMIT. Aun así, las consultas en paralelo podrían usarse para fases de consulta anteriores con GROUP BY, ORDER BY o uniones.

Operadores de comparación

El optimizador estima cuántas filas analizar para evaluar los operadores de comparación y determina si usar las consultas en paralelo en función de dicha estimación.

El primer ejemplo a continuación muestra que puede realizarse una comparación de igualdad con respecto a la columna de clave principal con eficacia sin usar consultas en paralelo. El segundo ejemplo a continuación muestra que una comparación similar con respecto a una columna no indexada requiere el análisis de millones de filas y, por tanto, puede sacar partido de las consultas en paralelo.

mysql> explain select * from part where p_partkey = 10; +----+...+------+-------+ | id |...| rows | Extra | +----+...+------+-------+ | 1 |...| 1 | NULL | +----+...+------+-------+ mysql> explain select * from part where p_type = 'LARGE BRUSHED BRASS'; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+

Se aplican las mismas consideraciones para pruebas de desigualdad y para comparaciones de rango, como de menor que, mayor que, igual a, o BETWEEN. El optimizador estima el número de filas que analizar y determina si vale la pena usar consultas en paralelo en función del volumen general de E/S.

Uniones

Las consultas de unión con tablas grandes suelen implicar operaciones con un uso intensivo de datos que se benefician de la optimización de consultas en paralelo. Las comparaciones de valores de columnas entre tablas múltiples (es decir, los predicados de unión en sí) actualmente no se paralelizan. Sin embargo, las consultas en paralelo pueden bajar algunos de los procesamientos internos para otras fases de unión, como la construcción del filtro de Bloom durante una unión de hash. Las consultas en paralelo se pueden aplicar a consultas de unión incluso sin una cláusula WHERE. Por tanto, una consulta de unión es una excepción a la regla de que se requiere una cláusula WHERE para usar las consultas en paralelo.

Cada fase del procesamiento de unión se evalúa para comprobar si es apto para las consultas en paralelo. Si varias fases pueden usar consultas en paralelo, estas fases se realizan en secuencia. Por tanto, cada consulta de unión cuenta como una sola sesión de consultas en paralelo en términos de límites de simultaneidad.

Por ejemplo, cuando una consulta incluye predicados WHERE para filtrar las filas de una de las tablas unidas, esa opción de filtrado puede usar las consultas en paralelo. Como otro ejemplo, suponga que una consulta de unión usa el mecanismo de unión de hash, por ejemplo, para unir una tabla grande con una tabla pequeña. En este caso, el análisis de tabla para producir la estructura de datos de filtro de Bloom podría usar consultas en paralelo.

nota

La consulta en paralelo se utiliza típicamente para los tipos de consultas que consumen más recursos que se benefician de la optimización de la combinación hash. El método para activar la optimización de uniones hash depende de la versión de Aurora MySQL. Para obtener información acerca de cada versión, consulte Activación de una combinación hash para clústeres de consultas paralelas. Para obtener información acerca de cómo utilizar combinaciones hash de manera eficaz, consulte Optimización de grandes consultas combinadas de Aurora MySQL con combinaciones hash.

mysql> explain select count(*) from orders join customer where o_custkey = c_custkey; +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | id |...| table | type | possible_keys | key |...| rows | Extra | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | 1 |...| customer | index | PRIMARY | c_nationkey |...| 15051972 | Using index | | 1 |...| orders | ALL | o_custkey | NULL |...| 154545408 | Using join buffer (Hash Join Outer table orders); Using parallel query (1 columns, 0 filters, 1 exprs; 0 extra) | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+

En el caso de una consulta de unión que use el mecanismo de bucle anidado, el bloque de bucle anidado más exterior podría usar consultas en paralelo. El uso de las consultas en paralelo depende de los factores habituales, como la presencia de condiciones de filtro adicionales en la cláusula WHERE.

mysql> -- Nested loop join with extra filter conditions can use parallel query. mysql> explain select count(*) from part, partsupp where p_partkey != ps_partkey and p_name is not null and ps_availqty > 0; +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | | 1 | SIMPLE | partsupp |...| 78164450 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+

subconsultas

El bloque de consulta externa y el bloque de subconsulta interna es posible que usen cada una la consulta paralela o no. Si lo hacen es en función de las características habituales de la tabla, cláusula WHERE, etc., para cada bloque. Por ejemplo, la siguiente consulta usa consultas en paralelo para el bloque de subconsulta, pero no el bloque exterior.

mysql> explain select count(*) from part where --> p_partkey < (select max(p_partkey) from part where p_name like '%vanilla%'); +----+-------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| NULL | Impossible WHERE noticed after reading const tables | | 2 | SUBQUERY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+-------------+...+----------+----------------------------------------------------------------------------+

Actualmente, las subconsultas correlacionadas no pueden usar la optimización de consultas en paralelo.

UNION

Cada bloque de consulta de una consulta de UNION puede usar o no usar consultas en paralelo, en función de las características habituales de la tabla, la cláusula WHERE, etc., para cada parte de UNION

mysql> explain select p_partkey from part where p_name like '%choco_ate%' -> union select p_partkey from part where p_name like '%vanil_a%'; +----+----------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+----------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | 2 | UNION |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | NULL | UNION RESULT | <union1,2> |...| NULL | Using temporary | +----+--------------+...+----------+----------------------------------------------------------------------------+
nota

Cada cláusula UNION de la consulta se ejecuta secuencialmente. Incluso aunque la consulta incluya varias fases que todas usen consultas en paralelo, solo ejecuta una sola consulta en paralelo cada vez. Por tanto, incluso una consulta multifase compleja solo cuenta como 1 para el límite de consultas en paralelo simultáneas.

Vistas

El optimizador reescribe cualquier consulta que use una vista como una consulta mayor que use las tablas subyacentes. Por tanto, las consultas en paralelo funcionan igual tanto si las referencias de tabla son vistas como si son tablas reales. Las mismas consideraciones sobre si usar consultas en paralelo para una consulta y qué partes se deben bajar también se aplican a la consulta reescrita final.

Por ejemplo, el siguiente plan de consulta muestra una definición de consulta que normalmente no usa consultas paralelas. Cuando se consulta la vista con cláusulas WHERE adicionales, Aurora MySQL usa consultas en paralelo.

mysql> create view part_view as select * from part; mysql> explain select count(*) from part_view where p_partkey is not null; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 0 filters, 0 exprs; 1 extra) | +----+...+----------+----------------------------------------------------------------------------+

Instrucciones de lenguaje de manipulación de datos (DML)

La instrucción INSERT puede usar consultas en paralelo para la fase SELECT de procesamiento, si la parte SELECT cumple las demás condiciones para las consultas en paralelo.

mysql> create table part_subset like part; mysql> explain insert into part_subset select * from part where p_mfgr = 'Manufacturer#1'; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+
nota

Normalmente, después de una instrucción INSERT, los datos de las filas recién insertadas se encuentran en el grupo de búfer. Por tanto, una tabla podría no ser apta para las consultas en paralelo inmediatamente después de insertar un gran número de filas. Más tarde, cuando los datos se desalojen del grupo de búfer durante el funcionamiento normal, las consultas con respecto a la tabla podrían comenzar a usar las consultas en paralelo de nuevo.

La instrucción CREATE TABLE AS SELECT no usa consultas en paralelo, incluso aunque la porción SELECT de la instrucción fuera apta de otra forma para la consultas en paralelo. El aspecto de DDL de esta instrucción hace que sea incompatible con el procesamiento de consultas en paralelo. Por el contrario, en la instrucción INSERT ... SELECT, la porción SELECT puede usar consultas en paralelo.

Las consultas en paralelo nunca se usan para las instrucciones DELETE o UPDATE, independientemente del tamaño de la tabla y los predicados de la cláusula WHERE.

mysql> explain delete from part where p_name is not null; +----+-------------+...+----------+-------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+-------------+ | 1 | SIMPLE |...| 20427936 | Using where | +----+-------------+...+----------+-------------+

Transacciones y bloqueo

Puede usar todos los niveles de aislamiento de la instancia principal de Aurora.

En las instancias de base de datos de lector de Aurora, la consulta en paralelo se aplica a las sentencias realizadas bajo el nivel de aislamiento REPEATABLE READ. La versión 2.09 o posteriores de Aurora MySQL también pueden usar el nivel de aislamiento READ COMMITTED en instancias de base de datos de lector. REPEATABLE READ es el nivel de aislamiento predeterminado para las instancias de base de datos de lector de Aurora. Para utilizar el nivel de aislamiento READ COMMITTED en instancias de base de datos de lector es necesario establecer la opción de configuración aurora_read_replica_read_committed en el nivel de sesión. El nivel de aislamiento de READ COMMITTED para las instancias del lector cumple con el comportamiento estándar de SQL. Sin embargo, el aislamiento es menos estricto en las instancias del lector que cuando las consultas utilizan el nivel de aislamiento de READ COMMITTED en la instancia del escritor.

Para obtener más información acerca de los niveles de aislamiento de Aurora, especialmente las diferencias en READ COMMITTED entre instancias del escritor y del lector, consulte Niveles de aislamiento de Aurora MySQL.

Después de terminar una gran transacción, las estadísticas de tabla podrían quedar obsoletas. Dichas estadísticas obsoletas podrían requerir una instrucción ANALYZE TABLE antes de que Aurora pueda estimar con precisión el número filas. Una instrucción DML a gran escala también podría aportar una porción sustancial de los datos de tabla en el grupo de búfer. Tener estos datos en el grupo de búfer puede dar lugar a que las consultas en paralelo se elijan con menos frecuencia para esa tabla hasta que los datos se desalojen del grupo.

Cuando su sesión esté dentro de una transacción de ejecución prolongada (por ejemplo, 10 minutos), las consultas posteriores dentro de la sesión no usan consultas en paralelo. También puede agotarse el tiempo de espera durante una única consulta de ejecución prolongada. Este tipo de finalización del tiempo de espera podría ocurrir si la consulta se ejecuta durante más del intervalo máximo (actualmente, 10 minutos) antes de que empiece el procesamiento de las consultas en paralelo.

Puede reducir las posibilidades de iniciar transacciones de ejecución prolongada accidentalmente estableciendo autocommit=1 en las sesiones de mysql en las que realiza consultas ad hoc (de una vez). Incluso una instrucción SELECT con respecto a una tabla inicia una transacción creando una vista de lectura. Una vista de lectura es un conjunto de datos uniforme para consultas posteriores que permanece hasta que la transacción se confirme. Tenga en cuenta esta restricción también al usar aplicaciones de JDBC u ODBC con Aurora porque tales aplicaciones podrían ejecutarse con el ajuste autocommit desactivado.

En el siguiente ejemplo se muestra cómo, con el ajuste autocommit desactivado, ejecutar una consulta contra una tabla crea una vista de lectura que inicia implícitamente una transacción. Las consultas que se ejecutan poco después pueden seguir usando consultas en paralelo. Sin embargo, después de una pausa de varios minutos, las consultas ya no son aptas para las consultas en paralelo. Terminar la transacción con COMMIT o ROLLBACK restaura la elegibilidad de las consultas en paralelo.

mysql> set autocommit=0; mysql> explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+ mysql> select sleep(720); explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +------------+ | sleep(720) | +------------+ | 0 | +------------+ 1 row in set (12 min 0.00 sec) +----+...+---------+-------------+ | id |...| rows | Extra | +----+...+---------+-------------+ | 1 |...| 2976129 | Using where | +----+...+---------+-------------+ mysql> commit; mysql> explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+

Para ver cuántas veces las consultas no fueron aptas para consultas en paralelo porque estaban dentro de transacciones de ejecución prolongada, consulte la variable de estado Aurora_pq_request_not_chosen_long_trx.

mysql> show global status like '%pq%trx%'; +---------------------------------------+-------+ | Variable_name | Value | +---------------------------------------+-------+ | Aurora_pq_request_not_chosen_long_trx | 4 | +-------------------------------+-------+

Cualquier instrucción SELECT que adquiera bloqueos, como la sintaxis de SELECT FOR UPDATE o SELECT LOCK IN SHARE MODE, no puede usar consultas en paralelo.

Las consultas en paralelo pueden funcionar para una tabla que esté bloqueada por una instrucción LOCK TABLES.

mysql> explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055'; +----+...+-----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+-----------+----------------------------------------------------------------------------+ | 1 |...| 154545408 | Using where; Using parallel query (3 columns, 1 filters, 0 exprs; 0 extra) | +----+...+-----------+----------------------------------------------------------------------------+ mysql> explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055' for update; +----+...+-----------+-------------+ | id |...| rows | Extra | +----+...+-----------+-------------+ | 1 |...| 154545408 | Using where | +----+...+-----------+-------------+

Índices de árbol B

Las estadísticas reunidas por la instrucción ANALYZE TABLE ayudan al optimizador a decidir cuándo usar las consultas en paralelo o las búsquedas de índice, según las características de los datos de cada columna. Para mantener las estadísticas actualizadas, ejecute ANALYZE TABLE después de las operaciones de DML que realicen cambios sustanciales en los datos de una tabla.

Si las búsquedas de índice pueden realizar una consulta de manera eficaz sin un análisis con uso intensivo de datos, Aurora podría usar búsquedas de índice. Esto evita el gasto general del procesamiento de las consultas en paralelo. También existen límites de simultaneidad sobre el número de consultas en paralelo que se pueden ejecutar a la vez en cualquier clúster de base de datos Aurora. Asegúrese de usar las prácticas recomendadas para indexar sus tablas, de forma que sus consultas más frecuentes y de mayor simultaneidad usen búsquedas de índice.

Índices de búsqueda de texto completo (FTS)

Actualmente, la consulta paralela no se usa para tablas que contengan un índice de búsqueda de texto completo, independientemente de si la consulta se refiere a dichas columnas indexadas o si usa el operador MATCH.

Virtual columns

Actualmente, la consulta paralela no se utiliza para tablas que contienen una columna virtual, independientemente de si la consulta se refiere a columnas virtuales.

Mecanismos de almacenamiento en caché integrados

Aurora incluye mecanismos de almacenamiento en caché integrados, es decir, el grupo de búfer y el caché de las consultas. El optimizador de Aurora elige entre estos mecanismos de almacenamiento en caché y las consultas en paralelo en función de cuál es más eficaz para una consulta concreta.

Cuando una consulta en paralelo filtra filas y transforma y extrae valores de columna, los datos se transmiten de vuelta al nodo director como tuplas en lugar de como páginas de datos. Por tanto, ejecutar una consulta en paralelo no añade ninguna página al grupo de búfer ni desaloja páginas que ya estén en el grupo de búfer.

Aurora verifica el número de páginas de datos de tabla que están presentes en el grupo de búfer y qué proporción de los datos de tabla representa ese número. Aurora utiliza esa información para determinar si es más eficaz para usar consultas en paralelo (y omitir los datos del grupo de búfer). De manera alternativa, Aurora podría usar la ruta de ejecución de consultas no paralelas, que usa los datos almacenados en caché en el grupo de búfer. Las páginas que se almacenan en caché y cómo afectan las consultas con uso intensivo de datos al almacenamiento en caché y la expulsión dependen de la configuración relacionada con el grupo de búfer. Por tanto, puede ser difícil predecir si una consulta concreta usará consultas en paralelo porque la elección depende de los datos que cambian en el grupo de búfer.

Además, Aurora impone límites de simultaneidad en las consultas paralelas. Puesto que no todas las consultas usan consultas en paralelo, las tablas a las que acceden múltiples consultas simultáneamente suelen tener una porción importante de sus datos en el grupo de búfer. Por tanto, Aurora no suele elegir estas tablas para consultas en paralelo.

Cuando ejecute una secuencia de consultas no paralelas en la misma tabla, la primera consulta podría ser lenta debido a que los datos no estén en el grupo de búfer. Después, la segunda consulta y las posteriores son mucho más rápidas puesto que el grupo de búfer ha "calentado". Las consultas en paralelo suelen mostrar un rendimiento uniforme desde la primera consulta respecto a la tabla. Al realizar pruebas de rendimiento, haga un análisis comparativo de las consultas no paralelas con un grupo de búfer frío y otro caliente. En algunos casos, los resultados con un grupo de búfer caliente se pueden comparar bien con los tiempos de consultas en paralelo. En estos casos, tenga en cuenta factores como la frecuencia de consultas en esa tabla. También considere si vale la pena mantener los datos de esa tabla en el grupo de búferes.

El caché de la consulta evita volver a ejecutar una consulta cuando se ha enviado una consulta idéntica y los datos de la tabla subyacente no han cambiado. Las consultas optimizadas por la característica de consultas en paralelo pueden ir a la caché de consultas, lo que hace que sean instantáneas la siguiente vez que se ejecuten.

nota

Al realizar comparaciones de rendimiento, la caché de consultas puede producir números de tiempos artificialmente bajos. Por tanto, en situaciones de análisis comparativo, puede usar la señal sql_no_cache. Esta señal evita que el resultado se sirva desde la caché de consultas, incluso aunque se haya ejecutado la misma consulta previamente. La señal va inmediatamente después de la instrucción SELECT en una consulta. Muchos ejemplos de consultas en paralelo de este tema incluyen esta señal, para que los tiempos de consultas sean comparables entre las versiones de la consulta que están activadas con las consultas en paralelo y las que no.

Asegúrese de quitar esta señal de su origen cuando pase a usar en producción las consultas en paralelo.

Sugerencias del optimizador

Otra forma de controlar el optimizador es mediante el uso de sugerencias del optimizador, que se pueden especificar en instrucciones individuales. Por ejemplo, puede activar la optimización para una tabla en una instrucción y, a continuación, desactivarla para otra tabla. Para obtener detalles sobre estas sugerencias, consulte Optimizer Hints (Sugerencias del optimizador) en el Manual de referencia de MySQL.

Puede utilizar consejos de SQL con consultas de Aurora MySQL para ajustar el rendimiento. También puede utilizar sugerencias para evitar que los planes de ejecución de consultas importantes cambien en función de condiciones impredecibles.

Hemos ampliado la característica de sugerencias de SQL para ayudarle a controlar las opciones del optimizador para sus planes de consultas. Estas sugerencias se aplican a las consultas que utilizan la optimización de consultas paralelas. Para obtener más información, consulte Sugerencias de Aurora MySQL.

Tablas temporales MyISAM

La optimización de consultas en paralelo solo se aplica a las tablas InnoDB. Dado que Aurora MySQL usa MyISAM en segundo plano para las tablas temporales, las fases de consultas internas que impliquen tablas temporales nunca usan consultas en paralelo. Estas fases de consultas se indican mediante Using temporary en la salida EXPLAIN.