Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

ORDER BY sobrecarga

Estas en el tema de ORDER BY sobrecarga en el foro de Mysql en Foros del Web. Hola, Estoy probando en optimizar una consulta sql y viendo que si uso el ORDER BY el tiempo que tarda en ejecutarla es mucho mayor. ...
  #1 (permalink)  
Antiguo 17/02/2014, 09:52
 
Fecha de Ingreso: febrero-2010
Mensajes: 45
Antigüedad: 14 años, 9 meses
Puntos: 1
ORDER BY sobrecarga

Hola,

Estoy probando en optimizar una consulta sql y viendo que si uso el ORDER BY el tiempo que tarda en ejecutarla es mucho mayor.

La consulta es esta:

Código SQL:
Ver original
  1. SELECT HIGH_PRIORITY a.id, ... FROM articulo a WHERE a.id_categoria!=0 AND a.eliminado=0 AND a.activado=1 AND a.descartado=0 AND a.imagen!='' AND a.nombre_min!='' AND a.id_seccion=2 AND a.id_empresa=1529 ORDER BY a.fecha_actualizado DESC LIMIT 0, 60

Tarda aproximadamente: 0.1824 seg. Mientras que si quito el order by: 0.0011 seg

El campo fecha_actualizado es un timestamp y lo tengo indexado para que la consulta vaya más rápido ya que es una de las consultas más usadas en la plataforma y que tarde casi 0,2 segundos me parece un espanto pero no se como hacer que la genere más rápido.

Todos los campos de id_secc.. etc tb están indexados. En sí, he probado variando todas las condiciones quitándolas para ver si era alguna de esas y la consulta me va igual, la única variación de rendimiento es cuando añado el order by fecha_actualizado.

También queda decir que la tabla tiene aproximadamente unos 2 millones de registros.

Haciendo un explain de la consulta los valores obtenidos han sido:

id: 1
select_type: simple
table: a
type: index_merge
possible_keys: id_empresa,id_categoria,eliminado,activado,descart ado,id_seccion
key: id_empresa,id_seccion
key_len: 4, 2
ref: NULL
rows: 2072
Extra: Using intersect(id_empresa,id_seccion); Using where

Parece que mediante explain me muestra que no esa usando el index de fecha_actualizado, pero no estoy seguro.

Agradecería si alguien me pudiera echar un cable.
Un saludo.
  #2 (permalink)  
Antiguo 17/02/2014, 10:00
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: ORDER BY sobrecarga

Prueba usando FORCE INDEX:

Código MySQL:
Ver original
  1. FROM articulo a FORCE INDEX fecha_actualizado
  2.     a.id_categoria!=0
  3.     AND a.eliminado=0
  4.     AND a.activado=1
  5.     AND a.descartado=0
  6.     AND a.imagen!=''
  7.     AND a.nombre_min!=''
  8.     AND a.id_seccion=2
  9.     AND a.id_empresa=1529
  10. ORDER BY a.fecha_actualizado DESC
  11. LIMIT 0, 60

Por otro lado, tienes demasiadas condiciones en el WHERE a evaluar, lo que no es una buena idea. Posiblemente se pueda mejorar usando las tablas relacionadas con sus JOINs, como las de categorías y empresas, lo que permitría quitar algunas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 17/02/2014, 10:54
 
Fecha de Ingreso: febrero-2010
Mensajes: 45
Antigüedad: 14 años, 9 meses
Puntos: 1
Respuesta: ORDER BY sobrecarga

Gracias gnzsoloyo,

Lo acabo de probar ahora mismo

Código MySQL:
Ver original
  1. FORCE INDEX ( fecha_actualizado)

Y mira que resultado me lanza mysql con el explain:


id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a index id_empresa fecha_actualizado 4 NULL 82 Using where

Se está saltando los otros indices. No lo llego a entender bien, y aún asi si fuerzo el indice de fecha, id_categoria e id_seccion sigue sogiendo solo el indice de fecha_actualizado, los otros los omite aunque los esté forzando.
  #4 (permalink)  
Antiguo 17/02/2014, 11:09
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: ORDER BY sobrecarga

El forzado sólo aplica al primero que se indica. Forzar los otros no genera cambios.
Por otro lado, no veo que hayas cosniderado el resto de las cosas que te dije, respecto a JOIs para mejroar las condicioens.
Como te dije, ese WHERE es muy ineficiente..
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 17/02/2014, 11:20
 
Fecha de Ingreso: febrero-2010
Mensajes: 45
Antigüedad: 14 años, 9 meses
Puntos: 1
Respuesta: ORDER BY sobrecarga

Sí, le he estado dando vueltas a lo que me habías dicho pero no se si lo había entendido bién.

Me dices que es mejor que use joins en id_seccion e id_categoria para optimizarla mejor?

Podría ser esto una solución?

Código MySQL:
Ver original
  1. FROM articulo a
  2.  
  3. INNER JOIN categoria c ON c.id=a.id_categoria AND a.id_categoria=13
  4. INNER JOIN seccion s ON s.id=a.id_seccion AND a.id_seccion=2
  5. INNER JOIN empresa e ON e.id=a.id_empresa AND a.id_empresa=1529
  6.  
  7.     AND a.eliminado=0
  8.     AND a.activado=1
  9.     AND a.descartado=0
  10.     AND a.imagen!=''
  11.     AND a.nombre_min!=''
  12.  
  13. ORDER BY a.fecha_actualizado DESC
  14. LIMIT 0, 60

Voy a probarlo

Perdón me he equivocado con el sql:

Código MySQL:
Ver original
  1. INNER JOIN categoria c ON c.id=a.id_categoria AND c.id=13
  2. INNER JOIN seccion s ON s.id=a.id_seccion AND s.id=2
  3. INNER JOIN empresa e ON e.id=a.id_empresa AND e.id=1529
  #6 (permalink)  
Antiguo 17/02/2014, 11:25
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: ORDER BY sobrecarga

No pongas las condiciones parametrizadas en el FROM... Es mala práctica.
Código SQL:
Ver original
  1. SELECT HIGH_PRIORITY a.id, ...
  2. FROM articulo a
  3.     INNER JOIN categoria c ON c.id=a.id_categoria
  4.     INNER JOIN seccion s ON s.id=a.id_seccion
  5.     INNER JOIN empresa e ON e.id=a.id_empresa
  6. WHERE
  7.     a.id_categoria=13
  8.     AND a.id_seccion=2
  9.     AND a.id_empresa=1529
  10.     AND a.eliminado=0
  11.     AND a.activado=1
  12.     AND a.descartado=0
  13.     AND a.imagen!=''
  14.     AND a.nombre_min!=''
  15.  
  16. ORDER BY a.fecha_actualizado DESC
  17. LIMIT 0, 60
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 17/02/2014, 11:27
 
Fecha de Ingreso: febrero-2010
Mensajes: 45
Antigüedad: 14 años, 9 meses
Puntos: 1
Respuesta: ORDER BY sobrecarga

No lo sabía, gracias. Estaba probando y no notaba mejora. Voy a modificarlo.
  #8 (permalink)  
Antiguo 17/02/2014, 11:35
 
Fecha de Ingreso: febrero-2010
Mensajes: 45
Antigüedad: 14 años, 9 meses
Puntos: 1
Respuesta: ORDER BY sobrecarga

Ahora lo tengo tal q así:

Código MySQL:
Ver original
  1. SELECT a.id...
  2.  
  3. FROM articulo a
  4. JOIN empresa e ON e.id=a.id_empresa
  5. JOIN seccion s ON s.id=a.id_seccion
  6. JOIN categoria c ON c.id=a.id_categoria
  7.  
  8.  
  9.  
  10. a.eliminado='0'
  11. AND a.activado='1'
  12.  
  13. AND e.id=1429
  14. AND s.id=1
  15. AND c.id=55
  16.  
  17. AND a.descartado='0'
  18. AND a.imagen!=''
  19. AND a.nombre_min!=''  
  20.  
  21. ORDER BY a.fecha_actualizado DESC LIMIT 0, 30

Pero me sigue dando 0,2 seg.

Están todos los campos que se concatenan con index en las 4 tablas (en la de articulo como index y en las otras como clave primaria). los id_categ e id_seccion son small int para q ocupen menos y la tabla tiene la información escasa para que salga en los listados. El único varchar que tiene la tabla es un campo para el título.
  #9 (permalink)  
Antiguo 17/02/2014, 12:22
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 7 meses
Puntos: 300
Respuesta: ORDER BY sobrecarga

No sé si servirá de algo, la verdad, pero yo intentaría este orden en el WHERE:
Código MySQL:
Ver original
  1. e.id=1429
  2. AND s.id=1
  3. AND c.id=55
  4.  
  5. AND a.eliminado='0'
  6. AND a.activado='1'
  7.  
  8.  AND a.descartado='0'
  9. AND a.imagen!=''
  10. AND a.nombre_min!=''

Etiquetas: campo, null, order, registro, select, sobrecarga, sql, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:42.