2016-04-02 3 views
5

Je viens du monde du front-end en développement web où nous essayons vraiment de limiter le nombre de requêtes HTTP émises (en consolidant les fichiers css, js, images, etc.). Avec les connexions db (MySQL), vous ne voulez évidemment pas avoir de connexions inutiles, mais en règle générale, quelle est la difficulté d'avoir plusieurs petites requêtes? (ils s'exécutent rapidement)à quel point est-il mauvais d'avoir des requêtes de base de données "extra"?

Je demande parce que je déplace mon application dans un environnement en cluster et où avant que je mettais en cache des choses dans la mémoire du serveur (comme je courais sur un seul serveur), j'essaie maintenant de faire mon application "sans état" et dans ma mise en œuvre actuelle qui signifie plus de petits appels db. Cela m'aidera à équilibrer la charge (éviter les sessions persistantes) et à réduire l'utilisation de la mémoire du serveur.

Nous ne parlons pas d'une tonne de requêtes, peut-être 6-8 appels db au lieu de 2-4, revenant n'importe où d'une poignée d'enregistrements à quelques milliers d'enregistrements. Chacun d'entre eux s'exécute rapidement, moins de 30ms (certains beaucoup moins), mais je ne sais pas s'il y a une certaine "latence de connexion" dont je devrais me préoccuper.

Merci pour votre avis.

+0

Brian Je serai heureux de pontifier un peu quand j'ai une chance mais pas pour l'instant – Drew

+0

Merci Drew, avec impatience votre perspicacité. –

+0

Toutes les règles ont des exceptions. Faites ce qu'il y a de mieux pour la situation actuelle. –

Répondre

5

Réponse courte: (1) assurez-vous que vous restez au même niveau de big-O, réutilisez les connexions, mesurez les performances; (2) pensez à quel point vous vous souciez de la cohérence des données.

Réponse longue:

Performance

strictement du point de vue de la performance, et d'une manière générale, à moins que vous êtes déjà près de plafonnait vos ressources de base de données, telles que les connexions max, il est peu probable d'avoir impact majeur. Mais il y a certaines choses que vous devez garder à l'esprit:

  • faire les requêtes « 6-8 » qui remplacent « 2-4 » requêtes restent dans le même temps d'exécution? par exemple. Si l'interaction de la base de données actuelle est à O(1), cela va-t-il changer à O(n)? Ou actuellement O(n) va passer à O(n^2)? Si oui, vous devriez penser à ce que cela signifie pour votre application
  • la plupart des serveurs d'applications peuvent réutiliser des connexions de base de données existantes, ou avoir des pools de connexion de base de données persistants; assurez-vous que votre application n'établit pas une nouvelle connexion pour chaque requête; sinon, cela rendra encore plus inefficace
  • dans de nombreux cas courants, principalement sur des tables plus grandes avec des index et des jointures complexes, faire quelques requêtes par des clés primaires peut être plus efficace que de rejoindre ces tables dans une seule requête; ce serait le cas si, en effectuant de telles jointures, le serveur prendrait plus de temps pour exécuter la requête complexe, mais bloquerait également les autres requêtes sur les tables affectées

Généralement parlant de performance, la règle générale est - toujours mesure.

Cohérence

Performance est pas le seul aspect à considérer, cependant. Pensez également à la façon dont vous vous souciez de la cohérence des données dans votre application. Par exemple, considérons un simple cas - tables A et B qui ont une relation un-à-un et vous interrogez un enregistrement unique en utilisant une clé primaire.Si vous joignez ces tables et récupérez le résultat en utilisant une seule requête, vous obtiendrez un enregistrement à la fois A et B, ou aucun enregistrement de l'un ou de l'autre, ce qui est ce que votre application attend également. Considérons maintenant si vous divisez cela en 2 requêtes (et vous n'utilisez pas les transactions avec les niveaux d'isolation préférés) - vous obtenez un enregistrement de la table A, mais avant de pouvoir récupérer l'enregistrement correspondant de la table B, il est supprimé/mis à jour par un autre processus. Maintenant, votre application a un enregistrement de A mais aucun de B.

La question générale ici est - vous souciez-vous de la conformité ACID de vos données relationnelles en ce qui concerne les requêtes que vous êtes en train de dissoudre? Si la réponse est oui, vous devez réfléchir à la façon dont votre logique d'application réagira dans ces cas spécifiques.

+0

Merveilleuse réponse, merci pour votre perspicacité! En ce qui concerne votre commentaire sur «toujours mesurer», y a-t-il un outil particulier que vous utilisez et que vous recommandez pour mesurer votre performance db? –

+0

Lorsque ColdFusion est en mode débogage, il peut être défini pour indiquer la durée d'exécution d'une requête. Il peut également montrer si la requête est mise en cache –

+0

@BrianFitzGerald Je suggère de mesurer les performances de l'application tout en surveillant la base de données (cpu, ram, connexions, requêtes lentes, etc.). Si vous avez un environnement que vous pouvez utiliser pour tester le chargement, ou si vous pouvez créer une pile séparée à cet effet, il devrait être assez simple de commencer avec le siège, apachebench, ou un outil similaire. –

4

6-8 requêtes pour une page Web? Habituellement, c'est bien. Je le fais tout le temps.

Des milliers de lignes sont-elles retournées? Étranglement! Qu'est-ce que le client va faire avec autant? Le SQL peut-il faire plus de traitement, puis retourner moins de lignes?

À de rares exceptions, seulement 1 connexion par page Web.

Chaque requête a beaucoup de frais généraux. Par exemple, INSERTing 100 lignes dans une table - 100 INSERT les instructions à une seule ligne prendront environ 10 fois plus longtemps qu'un seul 100 lignes INSERT. Donc, lorsque cela est pratique utiliser moins d'allers-retours au serveur. Cela devient très important si le réseau est un WAN. L'autre côté du globe est à 250 ms, juste pour la latence. Un serveur dans le même centre de données est probablement si proche que la latence peut être ignorée. Dans un réseau étendu, utilisez des routines stockées pour minimiser les allers-retours.

J'aime utiliser chaque requête dans le code. Ensuite, si je perçois un problème de performance, je cherche à voir sur quelle requête travailler en premier. Ou utilisez le SlowLog.

+1

Merci Rick! Quelques bons conseils là-bas. Et bon appel sur les milliers de lignes ... il s'agit essentiellement de pré-remplir l'objet utilisateur afin que je puisse faire quelque chose comme 'user.getFavorites()' (par exemple) et tous les favoris de l'utilisateur seront disponibles pour utilisation. J'obtiens ceux qui peuvent être paresseux chargés, etc., mais avant de devenir "sans état" l'utilisateur était mis en cache sur une base par session donc c'était un non-problème de préremplir une fois lors de l'initialisation de la session. De toute façon, vous m'avez convaincu de faire quelques changements architecturaux à mon application pour éviter de charger autant d'enregistrements sur chaque demande :) –