Question

Je suis en train d'obtenir optimize une requête très ancienne que je ne peux pas envelopper ma tête. le résultat que je veux archive est que je veux recommander le visiteur sur une boutique en ligne ce que les autres clients ont manifesté leur intérêt, à savoir ce que les autres qu'ils ont acheté avec le produit que le visiteur regarde.

J'ai une sous-requête, mais il est très lent, prend ~ 15s sur ~ 8 000 000 lignes.

la mise en page est que tous les produits qui sont mis dans un panier utilisateurs sont conservés dans un wsBasket de table et séparés par un basketid (qui, dans une autre table est associée à un membre).

dans cet exemple que je veux la liste de tous les produits les plus populaires que les utilisateurs ont achetés ensemble avec ProductID 427, mais pas la liste le ProductID lui-même 427.

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;

toute aide est très appréciée! espérons que cela a un sens tout au moins une personne:)

UPDATE 1: Merci pour vos commentaires gars voici mes réponses, ils ne correspondaient pas aux commentaires sur le terrain.

Utilisation EXPLIQUEZ sur la requête ci-dessus je suis le fllowing. S'il vous plaît noter, je n'ai pas d'index sur la table (à l'exception de clé primaire sur le id champ), je veux modifier la requête pour bénéficier des indices et des indices de place sur les touches droite.

+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| 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                                  |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
Était-ce utile?

La solution

Deux indices évidents d'ajouter: un sur basketid et une seconde sur ProductID: puis retenter la requête et une nouvelle EXPLIQUER pour voir que les index sont utilisés

Autres conseils

En plus d'assurer que les indices appropriés existent sur productid et basketid, vous souvent bénéficier de la structuration de votre requête comme une simple jointure plutôt qu'un sous-requête, en particulier dans 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

Pour moi, sur un ensemble de données peut-similaire, le join a donné lieu à deux rangées de select_type: SIMPLE dans la sortie EXPLAIN, alors que la méthode a craché une sous-requête DEPENDENT SUBQUERY horrible en fonction des résultats. Par conséquent, la jointure était bien plus d'un ordre de grandeur plus rapide.

Les deux champs que vous utilisez principalement pour la recherche dans cette requête sont ProductID et basketid.

Lorsque vous recherchez des enregistrements ayant ProductID égal à 427, la base de données n'a pas la moindre idée où trouver cet enregistrement. Il ne sait même pas que si elle ne trouve une correspondance, qu'il n'y aura pas un autre correspondant, il doit regarder à travers toute la table, potentiellement des milliers d'enregistrements.

Un index est un fichier séparé qui est triée, et ne contient que le champ / s vous êtes intéressé par le tri sur. créant ainsi un indice permet d'économiser une quantité énorme de temps!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top