¿Por qué la consulta de Mysql se vuelve lenta cuando agrego una columna para devolver?

IanM

Tengo una consulta que se está ejecutando lentamente (tanto en Mysql 8 como en MariaDB 10):

    select SQL_NO_CACHE UNIX_TIMESTAMP(created_at)* 1000 AS x,
           value AS y, day(created_at), month(created_at), year(created_at) 
    from `portfolios` 
    where `user_id` = 3 and (created_at)>( CURDATE() - INTERVAL 1 MONTH) 
    group by day(created_at),month(created_at), year(created_at) 
    order by `created_at` asc;

Si elimino la columna 'valor' de la selección, se ejecuta rápidamente.

La mesa es:

portfolios | CREATE TABLE `portfolios` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `value` decimal(15,8) NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `portfolios_user_id_created_at_index` (`user_id`,`created_at`),
  KEY `portfolios_user_id_updated_at_index` (`user_id`,`updated_at`),
  KEY `portfolios_id_user_id_updated_at_index` (`id`,`user_id`,`updated_at`),
  KEY `portfolios_user_id_index` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11767164 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

la tabla tiene alrededor de 12 millones de filas.

Ejecutando explicar (sin la columna 'valor'):

| id   | select_type | table      | type  | possible_keys                                                                                    | key                                 | key_len | ref  | rows   | Extra                                                     |
+------+-------------+------------+-------+--------------------------------------------------------------------------------------------------+-------------------------------------+---------+------+--------+-----------------------------------------------------------+
|    1 | SIMPLE      | portfolios | range | portfolios_user_id_created_at_index,portfolios_user_id_updated_at_index,portfolios_user_id_index | portfolios_user_id_created_at_index | 9       | NULL | 183996 | Using where; Using index; Using temporary; Using filesort |

Ejecutando explicar (con la columna 'valor'):

| id   | select_type | table      | type  | possible_keys                                                                                    | key                                 | key_len | ref  | rows   | Extra                                                  |
+------+-------------+------------+-------+--------------------------------------------------------------------------------------------------+-------------------------------------+---------+------+--------+--------------------------------------------------------+
|    1 | SIMPLE      | portfolios | range | portfolios_user_id_created_at_index,portfolios_user_id_updated_at_index,portfolios_user_id_index | portfolios_user_id_created_at_index | 9       | NULL | 184038 | Using index condition; Using temporary; Using filesort |

Entonces, cuando agrego esta columna a la consulta, parece dejar de 'usar dónde, usar índice' y comenzar a 'usar condición de índice'.

Realmente no entiendo por qué simplemente agregar una columna a la selección hace que esto se ralentice (15 segundos en comparación con aproximadamente .3): ​​¿se debe al tamaño de la tabla?

¡Agradecería cualquier consejo sobre cómo hacer que esto funcione más rápido!

Gracias por adelantado.

Salman A

Su petición consiste en tres columnas: user_id, created_aty value.

Tiene algunos índices en su tabla, pero ninguno de ellos contiene la valuecolumna. La explicación parece indicar que MySQL está usando el (user_id, updated_at)índice para filtrar las filas coincidentes, pero para generar el resultado completo, también escanea la tabla para extraer valores de la valuecolumna para las filas coincidentes.

Si crea un índice en (user_id, created_at, value)él, podría usarse como un índice de cobertura ... para que coincida con la cláusula where y para buscar valuedesde el índice. MySQL ya no necesita tocar la tabla de filas de 22 mil.


Además, tu GROUP BYes incorrecto. Supongo que debe contar o sumar los valores para cada día del año, en cuyo caso debe:

SELECT UNIX_TIMESTAMP(CAST(created_at AS DATE)) * 1000, SUM(values)
FROM t
WHERE ...
GROUP BY CAST(created_at AS DATE)
ORDER BY CAST(created_at AS DATE)

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

¿Por qué la consulta de Mysql se vuelve lenta cuando agrego una columna para devolver?

¿Por qué el componente no se vuelve a renderizar cuando agrego @action decorator a una función de controlador de eventos react

¿Por qué una columna se vuelve ambigua cuando ME UNO a una tabla?

¿Por qué la asignación de un grupo de MySQL a una variable miembro vuelve a indefinida cuando se llama a una función miembro?

¿Por qué la concatenación de DataFrames se vuelve exponencialmente más lenta?

La consulta PHP Mysql se vuelve extremadamente lenta después de agregar otro parámetro WHERE

¿Por qué la función de suma integrada de Python es lenta cuando se usa para aplanar una lista de listas?

cuando agrego la función de agrupación para crear una nueva columna en DF, no funciona como se esperaba

¿Por qué esta consulta da como resultado un escaneo de tabla cuando agrego una cláusula OR?

¿Por qué esta consulta da como resultado un escaneo de tabla cuando agrego una cláusula OR?

¿Por qué obtengo SQLCODE -206 cuando ejecuto una consulta para calcular el valor mediano de una columna?

¿Por qué se bloquea mi programa C cuando agrego una instrucción a la función principal?

La consulta T-SQL se vuelve muy lenta después de eliminar una gran cantidad de filas

Mariadb (MySQL): consulta lenta cuando se usa una subconsulta

¿Por qué cuando agrego \ para calcularlo, no se muestra en la salida?

Columna de números enteros crecientes: ¿por qué se necesita un índice para acelerar la consulta?

La consulta de selección de MySQL se vuelve bastante lenta con AMBOS dónde y orden descendente

¿Por qué NSView personalizado se vuelve a dibujar cuando se cambia el tamaño de la ventana o se mueve (arrastra) a una pantalla secundaria (monitor)?

Consulta SQL para devolver solo una fila cuando la identificación se encuentra en varias filas de otra tabla

¿Por qué devolvería un elemento de una función si lo agrego a una matriz global dentro de la función?

¿Por qué devolvería un elemento de una función si lo agrego a una matriz global dentro de la función?

¿Por qué cuando reasigno un valor a una variable dentro de una función, la variable se vuelve indefinida y obtengo un error de tipo?

Cuando agrego diferentes listas a una lista de listas, obtengo solo la última lista. ¿Por qué?

Cuando agrego diferentes listas a una lista de listas, obtengo solo la última lista. ¿Por qué?

¿Por qué la matriz de objetos se vuelve nula cuando Promise inside loop?

¿Por qué hay una gran diferencia entre los resultados de EXPLAIN y la consulta lenta?

No puedo entender por qué la consulta mysql es tan lenta

¿Por qué la altura no se comporta para un img en una columna de arranque?

¿Apollo vuelve a buscar la consulta cuando el componente se monta por segunda vez con el componente de consulta?