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                                  |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
È stato utile?

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!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top