2010-02-22 6 views
0

La requête:Quelle est la dangerosité de cette requête SQL?

UPDATE 
    node as n 
    right join content_type_product as c 
    on n.nid = c.nid 

    right join uc_products as p 
    on p.nid = n.nid 

    set 
     c.field_product_price_eur_value = p.sell_price * 0.0961, 
     c.field_product_price_zar_value = p.sell_price * 1, 
     c.field_product_price_gbp_value = p.sell_price * 0.0844, 
     c.field_product_price_usd_value = p.sell_price * 0.1305, 
     n.changed = now() 
    where n.type = 'product' 

Pour ceux qui n'ont pas pensé à elle, cette requête met à jour tous les noeuds sur un site Drupal à tous la dernière monnaie. Ma question est, est-elle dangereuse cette requête si vous avez:

  1. 500 nœuds
  2. 50 000 nœuds
  3. 1 000 000 nœuds

Si cette commande est exécutée toutes les heures?

Je dois savoir si je dois seulement exécuter cette requête toutes les quelques heures, ou si je dois limiter la mise à jour seulement dire 500 à la fois, etc.

Le site où il sera exécuté aura plusieurs noeuds entrées et cette requête a mis à jour 2 lignes pour chaque 1 produit. Donc, je ne suis pas sûr à quel point cela va fatiguer le serveur, si j'ai des tonnes de nœuds.

+0

Quel est votre SGBDR? – Lucero

+0

La question qui vient immédiatement à l'esprit est ce qui se passe si elle est interrompue ... –

+0

Base de données = MySQL (je cours Drupal) Et si elle est interrompue, ce n'est pas la fin du monde, car il fonctionne toutes les heures . La question est, va-t-il tuer le serveur (c'est-à-dire utiliser trop de traitement) s'il y a 1 000 000 de nœuds)? Gardez à l'esprit qu'il s'agit de mettre à jour les produits et que le site pourrait avoir beaucoup, beaucoup de produits. – coderama

Répondre

10

Je suggérerais d'effectuer une analyse comparative dans votre environnement de test (vous disposez d'un environnement de test, n'est-ce pas?) Pour estimer le type de charge que votre serveur rencontrerait. Il est très difficile de deviner quelle sorte d'impact cela aura sans en savoir plus sur votre environnement. Pour améliorer votre application, cependant, je suggère de stocker les taux de change dans un tableau séparé et de les calculer lorsque les utilisateurs tirent un produit particulier. De cette façon, vous n'avez pas besoin de mettre à jour des millions de lignes lorsque seulement une poignée de nombres ont réellement changé. Vous pouvez même mettre à jour vos taux de change toutes les quelques minutes plutôt que toutes les heures, si vous le souhaitez.

+0

Ceci, 100%. Vous avez une redondance des taux de change dans chaque produit - même si vous utiliserez un peu plus de temps pour calculer le prix réel dans le contrôleur, vous devriez sérieusement envisager de jeter les données redondantes dans un nouveau tableau afin de ne pas avoir à mettre à jour des millions des produits chaque fois que les taux de change changent du tout. –

+0

Comment pourrais-je comparer 1 000 000 produits sans créer réellement 1 000 000 de produits? Sur Drupal? Je suis d'accord, tester moi-même serait la meilleure façon de le faire, mais je n'aime pas l'idée de créer autant de données fausses. – coderama

+1

@RD: Ce ne sont pas des données fausses, ce sont des données de test. Dans votre environnement de test. * Ce que vous avez, non? * –

2

Ceci est, sans aucun doute, un appel assez lourd à faire. Je suppose que c'est pour mettre à jour les prix des produits selon les derniers taux de change. 1 000 000 de nœuds, c'est beaucoup, mais si vous avez plusieurs milliers de coups par seconde, cela peut entraîner plusieurs millions de calculs si cela est fait à la volée.

Ma seule recommandation serait de mettre en place une sorte de filtrage pour ne mettre à jour que les produits "actifs". Autrement dit, les produits qui sont visibles pour le public. Si un produit passe de inactif à actif, il devrait recueillir son prix approprié à ce moment-là.

+0

Cela m'a donné une idée. Que se passe-t-il si, à chaque fois qu'un produit est consulté, son prix est mis à jour? Hmmm. Cela pourrait faire l'affaire. – coderama

1

Est-ce une table InnoDB ou MyISAM? Si MyISAM, il va verrouiller la table complète pour l'ensemble de la requête, cela verrouillera toutes les lectures pendant un laps de temps considérable.

La requête en elle-même est OK, mais vérifiez avec EXPLAIN pour vous assurer que vous avez les bons index.

Vous pouvez également utiliser vid et mettre à jour uniquement la dernière révision de vos noeuds.

1
c.field_product_price_zar_value = p.sell_price * 1, 

Eh bien, cette partie est un gaspillage de ressources, prix * 1 = prix. En fait, puisque vous effectuez une mise à jour d'un montant fixe à chaque fois, je ne suis pas sûr que la requête fasse ce dont vous avez besoin de toute façon. En général cependant, je ne considérerais jamais mettre à jour tous les prix que j'ai sur un programme à moins qu'il y ait un changement les obligeant à changer. Il n'y a rien dans votre requête qui indique qu'un changement est survenu, donc il se produirait que la valeur de la monnaie change ou non (et la façon dont elle est écrite changerait les valeurs même si la devise n'a pas changé).OU ne vois-je pas une partie de votre processus?

Questions connexes