query per ciò che i clienti hanno acquistato insieme al prodotto elencato
Domanda
Sto cercando di ottenere ottimizzare un molto vecchio query che non posso avvolgere la mia testa intorno. il risultato che voglio archivio è che voglio consigliare il visitatore in un negozio web che cosa altri clienti hanno mostrato interesse, vale a dire che cosa hanno comprato insieme al prodotto che il visitatore sta guardando.
ho un subquery ma di molto lenta, prende ~ 15s su ~ 8 000 000 righe.
la disposizione è che tutti i prodotti che vengono messi in un cesto utenti sono memorizzate in una tabella di wsBasket
e separati da un basketid
(che in un'altra tabella è associato un utente registrato).
In questo esempio voglio elencare tutti i prodotti più popolari che gli utenti hanno acquistato insieme a ProductID 427, ma non elencare il ProductID 427 stesso.
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;
ogni aiuto è molto apprezzato! speriamo che questo abbia un senso a tutti di almeno qualcuno:)
UPDATE 1: Grazie per i vostri commenti ragazzi qui sono le mie risposte, che non rientravano nel commenti campo.
Utilizzando contare sulla query precedente ho avuto la fllowing. Si prega di notare, non ha gli indici della tabella (ad eccezione per la chiave primaria sul id
-campo), voglio modificare la query di beneficiare di indici e luogo indici sui tasti giusti.
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| 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 |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
Soluzione
Due indici evidenti da aggiungere: uno su basketid e un secondo su ProductID: quindi tentare nuovamente l'interrogazione e una nuova spiegare a vedere che gli indici vengono utilizzati
Altri suggerimenti
Oltre a garantire che gli indici adatti esistono sul productid
e basketid
, è spesso beneficiare di strutturazione query come un semplice unire piuttosto che una sottoquery, soprattutto in 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
Per me, su un insieme di dati eventualmente-simile, il join portato a due righe select_type: SIMPLE
nell'output EXPLAIN
, mentre il metodo subquery sputò un DEPENDENT SUBQUERY
orribile-per-prestazioni. Di conseguenza, l'adesione è stata ben più di un ordine di grandezza più veloce.
I due campi che si utilizzano principalmente per la ricerca in questa query sono ProductID e basketid.
Quando si cerca per i record che hanno productid pari a 427, di database non ha alcuna idea di dove trovare questo record. Non ha nemmeno sapere che se lo fa trovare uno di corrispondenza, che non ci sarà un altro abbinamento uno, quindi deve guardare attraverso l'intera tabella, potenzialmente migliaia di record.
Un indice è un file separato che è ordinato, e contiene solo il campo / s che ti interessa l'ordinamento su. in modo da creare un indice di risparmiare una quantità immensa di tempo!