Pregunta

Estoy intentando conseguir optimizar una consulta muy antiguo que no puedo envolver mi cabeza alrededor. el resultado que quiero archivo es que yo quiero recomendar al visitante en una tienda on-line lo que otros clientes han mostrado interés en, es decir, qué más se han comprado junto con el producto que el visitante está mirando.

tengo una subconsulta pero de muy lento, tarda unos 15 segundos en ~ 8 000 000 filas.

el diseño es que todos los productos que se ponen en una cesta de usuarios se mantienen en una wsBasket mesa y separadas por una basketid (que en otra mesa está asociado con un miembro).

En este ejemplo quiero una lista de todos los productos más populares que los usuarios han comprado junto con idproducto 427, pero no una lista de identificadores de producto 427 en sí.

SELECT productid, SUM(quantity) AS qty 
FROM wsBasket 
WHERE basketid IN 
    (SELECT basketid 
     FROM wsBasket 
     WHERE productid=427) AND productid!=427 
GROUP by productid 
ORDER BY qty 
DESC LIMIT 0,4;

cualquier ayuda es muy apreciada! Espero que esto tenga ningún sentido en absoluto a al menos alguien:)

ACTUALIZACIÓN 1: Gracias por tus comentarios chicos aquí están mis respuestas, no encajaban en los comentarios de campo.

Uso explique en la consulta anterior tengo el fllowing. Tenga en cuenta, no tenemos ninguna índices de la tabla (a excepción de clave principal en el campo de id), quiero modificar la consulta para beneficiarse de los índices y los índices en lugar de las teclas de la derecha.

+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type        | table    | type | possible_keys | key  | key_len | ref  | rows | Extra                                        |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
|  1 | PRIMARY            | wsBasket | ALL  | NULL          | NULL | NULL    | NULL | 2821 | Using where; Using temporary; Using filesort |
|  2 | DEPENDENT SUBQUERY | wsBasket | ALL  | NULL          | NULL | NULL    | NULL | 2821 | Using where                                  |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
¿Fue útil?

Solución

Dos índices obvias para añadir: uno en basketid y una segunda en idproducto: vuelva a intentar la consulta y una nueva explicar a ver que los índices se están utilizando

Otros consejos

Además de asegurar la existencia de índices adecuados en productid y basketid, que a menudo se beneficiarán de la estructuración de su consulta como una combinación sencilla en lugar de una subconsulta, especialmente en MySQL.

SELECT b1.productid, SUM(b1.quantity) AS qty
FROM wsBasket AS b0
JOIN wsBasket AS b1 ON b1.basketid=b0.basketid
WHERE b0.productid=427 AND b1.productid<>427
GROUP BY b1.productid
ORDER BY qty DESC
LIMIT 4

Para mí, en un conjunto de datos posiblemente-similares, la unión resultó en dos filas select_type: SIMPLE en la salida EXPLAIN, mientras que el método subconsulta escupió un DEPENDENT SUBQUERY horribles por rendimiento. En consecuencia la unión era más de un orden de magnitud más rápido.

Los dos campos que se utiliza principalmente para la búsqueda en esta consulta son idproducto y basketid.

Al buscar registros que tienen idproducto igual a 427, la base de datos no tiene idea de dónde encontrar este registro. Ni siquiera saber que si lo hace encontrar una coincidencia, que no habrá otro juego uno, por lo que tiene que mirar a través de toda la tabla, lo que potencialmente miles de registros.

Un índice es un archivo separado que se ordena, y contiene sólo el campo / s que estás interesado en la clasificación sucesivamente. por lo que la creación de un índice ahorra una cantidad inmensa de tiempo!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top