sql >> Base de Datos >  >> RDS >> Mysql

Consulta lenta de Mysql:UNIRSE + múltiples DÓNDE + ORDENAR POR

Los índices marcan una gran diferencia en mysql, una consulta que tomó 15 minutos con un conjunto incorrecto de índices tomó .2 segundos con los correctos, pero el problema generalmente es encontrar el equilibrio correcto. Naturalmente, sin algunos datos de muestra, es muy difícil decir si la siguiente solución le ahorrará tiempo, pero en teoría debería hacerlo.

Para responder a sus preguntas, rediseñaría las tablas así:

CREATE TABLE `product_all` ( 
`prod_id` INT( 10 ) NOT NULL, 
`ref_id` INT( 10) NOT NULL, 
`date` DATE NOT NULL , 
`buy_link` BLOB NOT NULL , 
`sale_price` FLOAT NOT NULL,
PRIMARY KEY (prod_id, ref_id) ,
INDEX date_Index (`date` ASC),
UNIQUE INDEX prod_price_Index (prod_id ASC, sale_price ASC)
) ENGINE = MYISAM ; 


CREATE TABLE `product_info` ( 
`prod_id` INT( 10 ) NOT NULL AUTO_INCREMENT, 
`prod_name` VARCHAR( 200 ) NOT NULL, 
`brand` VARCHAR( 50 ) NOT NULL, 
`retail_price` FLOAT NOT NULL, 
`category` INT( 3 ) NOT NULL, 
`gender` VARCHAR( 1 ) NOT NULL, 
`type` VARCHAR( 10 ) NOT NULL,
PRIMARY KEY (prod_id) ,
UNIQUE INDEX prod_id_name_Index (prod_id ASC, prod_name ASC),
INDEX category_Index (category ASC),
INDEX gender_Index (gender ASC)
) ENGINE = MYISAM ;

SELECT product_info.*, MIN(product_all.sale_price) as sale_price, product_all.buy_link         
FROM product_info         
NATURAL JOIN (SELECT * FROM product_all WHERE product_all.date = '2010-09-30') as product_all         
WHERE (product_info.category = 2           
AND product_info.gender = 'W' )         
GROUP BY product_all.prod_id         
ORDER BY MIN(product_all.sale_price) ASC LIMIT 13        

La ganancia de rendimiento aquí se obtiene al indexar los campos principales que se unen y se muestran en la cláusula where. Personalmente, iría con su primera consulta como cuando lo piensa, debería funcionar mejor.

Según tengo entendido, qué sucede en la primera y segunda consulta:

  • La primera consulta se filtra por una subconsulta antes de realizar la unión natural, lo que significa que solo se unen los datos resultantes y no toda la tabla.
  • La segunda consulta es unir toda la segunda tabla y luego filtrar las filas resultantes de todo el lote de nuevo a lo que desea.

Como regla general, normalmente desea agregar índices en sus principales campos de unión y también en los campos que más usa en las cláusulas where. También he puesto algunos índices únicos en algunos de los campos que querrá consultar regularmente, como prod_id_name_Index.

Si esto no mejora su rendimiento, si puede publicar algunos datos ficticios para jugar, podría obtener una solución más rápida que pueda comparar.

Aquí es un artículo que pasa por la indexación del rendimiento en mysql, vale la pena leerlo si quiere saber más.

¡Buena suerte!

EDITAR:Su pregunta final me perdí la primera vez, la respuesta es que si está indexando los campos de unión principales, luego cambia a donde solo afectará levemente el rendimiento general, pero los índices únicos que he puesto en las tablas deben tener en cuenta el mayoría de las cosas en las que querrá basar las consultas. Lo más importante que debe recordar es que si consulta o se une a un campo con frecuencia, entonces realmente debería estar indexado, pero las consultas menores y los cambios en el orden no deberían preocuparle en términos de realinear su estrategia de indexación.