2010-08-09 6 views
0

J'ai un modèle de données comme les suivantes:Faire une requête plus efficace pour les lectures

username | product1 | product2 
------------------------------- 
harold  abc  qrs 
harold  abc  def 
harold  def  abc 
kim  abc  def 
kim  lmn  qrs  
... 

username | friend_username 
--------------------------- 
john  harold 
john  kim 
... 

Je veux construire un histogramme de la product1 la plus fréquente aux dossiers produit2 il y a, limité à un id product1 donné, et limité seulement aux amis de John. Donc, quelque chose comme:

Que faire des amis de john lien pour pour product1, quand product1 = « abc »: Sélectionner tous les amis de john de la table d'amis. Pour chaque ami, compter et le groupe le nombre d'enregistrements où product1 = « abc », Trier les résultats par ordre desc:

Results: 
abc -> def (2 instances) 
abc -> qrs (1 instance) 

Je sais que nous pouvons faire ce qui suit dans une base de données relationnelle, mais il y aura un certain seuil où ce type de requête commencera à utiliser beaucoup de ressources. Les utilisateurs peuvent avoir un grand nombre d'enregistrements d'amis (500+). Si cette requête est exécutée 5 fois chaque fois qu'un utilisateur charge une page, je crains de manquer de ressources rapidement.

Y a-t-il une autre table que je peux présenter à mon modèle pour alléger la surcharge de la requête ci-dessus chaque fois que les utilisateurs veulent voir l'histogramme tomber en panne? Tout ce que je peux penser est de précalculer les histogrammes lorsque c'est possible afin que les lectures soient optimisées.

Merci pour toutes les idées

Répondre

0

Voici votre requête:

SELECT p.product2, 
     COUNT(p.product2) AS num_product 
    FROM PRODUCTS p 
    JOIN FRIENDS f ON f.friend_username = p.username 
        AND f.username = 'john' 
    WHERE p.product1 = 'abc' 
GROUP BY p.product2 
ORDER BY num_product DESC 

Pour gérer 5 produits, utilisez:

SELECT p.product1, 
     p.product2, 
     COUNT(p.product2) AS num_product 
    FROM PRODUCTS p 
    JOIN FRIENDS f ON f.friend_username = p.username 
        AND f.username = 'john' 
    WHERE p.product1 IN ('abc', 'def', 'ghi', 'jkl', 'mno') 
GROUP BY p.product1, p.product2 
ORDER BY num_product DESC 

Il est assez simple, et plus vous pouvez filtrer les enregistrements vers le bas , plus vite il fonctionnera car il s'agit d'un jeu de données plus petit.

Si cette requête est exécutée 5 fois chaque fois qu'un utilisateur charge une page, je crains de manquer rapidement de ressources.

Ma première question est pourquoi vous exécuteriez cette requête plus d'une fois par page. Si vous souhaitez couvrir plus d'un ami, la requête que j'ai publiée peut être mise à jour pour exposer le nombre de produits par ami ou utilisateur. Après cela, je me demande si la requête peut être mise en cache du tout. À quel point avez-vous vraiment besoin des données - est-ce que 2 heures sont acceptables? Que diriez-vous de 6 ou 12 ... Nous aurions tous comme les données pour être instantané, mais vous devez peser cela contre la performance et prendre une décision.

+0

Salut, ouais je voudrais montrer une page avec 5 produits par exemple. Ensuite, la requête ci-dessus devra être exécutée une fois pour chaque produit, pour trouver l'histogramme de chaque produit. D'accord, les données n'ont pas vraiment besoin d'être fraîches. Je me demandais vraiment si je manquais une stratégie évidente pour optimiser la requête. Je ne pense pas qu'il y ait, à la fin, vous devez vérifier N amis contre les enregistrements M product1 et les grouper pour construire l'histogramme. Nous avons donc besoin de stratégies pour empêcher l'exécution d'une telle requête ou la réduire en premier lieu. – user291701

+0

@ user291701: J'ai mis à jour la réponse pour inclure comment interroger 5 produits à la fois. J'ai ajouté le 'product1' à la sortie afin que vous sachiez quelle valeur' count2' est associée à la valeur 'product1'. –

+0

Nous vous remercions de votre aide. – user291701

Questions connexes