Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

182
Visualizações
Diferentes métodos de escritura de SQL causan diferentes costos de tiempo

Estoy tratando de select every n-th row from mysql , leí esta respuesta .

Hay una tabla sys_request_log :

 CREATE TABLE `sys_request_log` ( `id` bigint(20) NOT NULL, `user_id` bigint(20) DEFAULT NULL, `ip` varchar(50) DEFAULT NULL, `data` mediumtext, `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, KEY `user_id` (`user_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

Contiene 11837 filas.

Intento select every 5-th row from table , primero trato de ejecutar:

 SELECT * FROM (SELECT @ROW := @ROW + 1 AS rownum, log.* FROM ( SELECT @ROW := 0 ) r, sys_request_log log ) ranked WHERE rownum % 5 = 1

El resultado es:

 rownum id user_id create_time ------------------------------------------------------------------- 1 1271446699071639552 1 2020-06-12 22:18:10 6 1271446948980854784 1 2020-06-12 22:19:10 11 1271447016878247936 1269884071484461056 2020-06-12 22:19:26

Cuesta 1.001s de tiempo

Encontré que hay una columna no relacionada rownum . Así que modifico el SQL así:

 SELECT log.* FROM (SELECT @ROW := @ROW + 1 AS rownum FROM (SELECT @ROW := 0) t) r, sys_request_log log WHERE rownum % 5 = 1

Ahora el resultado es limpio (sin número de fila), ¡pero cuesta 2.516 s de tiempo!

¿Por qué?

Versión de Mysql: 5.7.26-registro

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

En el primer caso, los valores del número de fila se seleccionan durante la selección de la tabla ( sys_request_log ), pero en el segundo caso se produce un producto cartesiano entre la subconsulta r y la selección de la tabla debido a la ocurrencia de CROSS JOIN para cada número de fila individual. frente a cada valor de fila individual de la tabla.

over 4 years ago · Santiago Trujillo Relatório

0

Si entiendo correctamente, puede hacer lo que quiera moviendo la asignación de variables a la cláusula where :

 select srl.* from sys_request_log srl cross join (select @rn := 0) params where (@rn := (@rn + 1)) % 5 = 1;

Tenga en cuenta que esto funciona en este caso, porque la consulta debe realizar un escaneo completo de la tabla y ejecutar la cláusula WHERE en cada fila. Puede que no funcione si la consulta tiene JOIN , GROUP BY u ORDR BY .

El uso de variables de esta manera está obsoleto en MySQL ahora. Debe actualizar y aprender sobre las funciones de la ventana.

over 4 years ago · Santiago Trujillo Relatório

0

Su segunda consulta tiene un resultado diferente al de la primera y devuelve todas las filas, así que tómese mucho más tiempo que la primera.

Para eliminar el número de rownum de la primera consulta, solo nombre los campos en la cláusula SELECT.

prueba esto:

 SELECT ranked.id, ranked.user_id ,ranked.create_time FROM ( SELECT @ROW := @ROW + 1 AS rownum, log.* FROM ( SELECT @ROW := 0 ) r, sys_request_log log ) ranked WHERE rownum % 5 = 1
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda