(ASP.NET) Comment iriez-vous sur la création d'un compteur en temps réel qui permet de suivre les changements de base de données?

StackOverflow https://stackoverflow.com/questions/1072067

Question

Voici la question.

Sur un site que j'ai récemment pris sur elle les pistes « miles » vous couru en un jour. Ainsi, un utilisateur peut se connecter sur le site, ajouter que ils ont couru 5 miles. Il est ensuite ajouté à la base de données.

A la fin de la journée, vers 1h du matin, un service court qui calcule tous les miles, tous les utilisateurs couru dans la journée et génère un fichier texte à App_Data. Ce fichier texte est alors affiché en flash sur la page d'accueil.

Je pense que cela est un peu ridicule. On m'a dit qu'ils devaient le faire en raison de problèmes massifs de performance. Ils ne vont pas me dire exactement comment ils le faisaient avant ou que le principal problème de performance était.

Alors, quelle approche vous les gars prendre? La première chose qui me vint à l'esprit était un service Web qui obtient les données via un appel AJAX. Peut-être à chaque fois une nouvelle entrée « mile » est ajouté, un déclencheur est tiré et met à jour la table « GlobalMiles ».

Je vous remercie de toute information ou des conseils sur ce sujet.

Merci beaucoup!

Était-ce utile?

La solution

La réponse à cette question est un peu difficile car il nous ne savons pas tous vos besoins et quelque chose ne fonctionnait pas avant. Alors, voici quelques idées différentes.

Tout d'abord, revoir vos hypothèses. Génération d'un rapport statique une fois par jour est une solution parfaitement valable si vous avez besoin est des rapports quotidiens. Pourquoi frapper la base de données plusieurs fois throghout le jour si tout ce qui est nécessaire est un instantané (par exemple, beaucoup de logiciel de blog utilisé pour écrire des fichiers html quand un blog a été posté au lieu de servir l'entrée de la base de données à chaque fois - beaucoup le font encore comme une optimisation). Est-ce la fonction « en temps réel » quelque chose que vous ajoutez?

Je ne sauterais pas à AJAX tout de suite. Utilisez la même méthode d'entrée, il suffit de déplacer le rapport de statique dynamique. Faire trop à la fois est une bonne façon de vous faire enterrer. Lors de la modification du code existant j'essaie de trouver des domaines que je peux changer dans l'isolement wih le moins d'impact sur le reste de l'application. Ensuite, une fois que vous avez le rapport dynamique vous pouvez ajouter AJAX (et s'il vous plaît utiliser progressive amélioration ).

En ce qui concerne le rapport dynamique lui-même vous avez quelques options.

Bien sûr, vous pouvez simplement SELECT SUM (), mais il semble que cela causerait des problèmes de performance si chaque utilisateur dispose d'un grand nombre d'entrées.

Si votre base de données prend en charge, je chercherais à l'aide d'un vue indexée (parfois appelé une vue matérialisée). Il devrait soutenir les mises à jour permet rapidement aux données de somme en temps réel:

CREATE VIEW vw_Miles WITH SCHEMABINDING AS 
SELECT SUM([Count]) AS TotalMiles, 
COUNT_BIG(*) AS [EntryCount],
UserId
FROM Miles
GROUP BY UserID
GO
CREATE UNIQUE CLUSTERED INDEX ix_Miles ON vw_Miles(UserId)

Si la surcharge de c'est trop, la solution de @ jn29098 est une bonne fois. Rouler à l'aide d'une tâche planifiée. S'il y a beaucoup d'entrées pour chaque utilisateur, vous ne pouvez ajouter le delta de la dernière fois que la tâche a été exécutée.

UPDATE GlobalMiles SET [TotalMiles] = [TotalMiles] + 
  (SELECT SUM([Count]) 
    FROM Miles 
    WHERE UserId = @id 
      AND EntryDate > @lastTaskRun
    GROUP BY UserId)
WHERE UserId = @id

Si vous ne se soucient pas de stocker les entrées individuelles, mais seulement le total que vous pouvez mettre à jour le compte à la volée:

UPDATE Miles SET [Count] = [Count] + @newCount WHERE UserId = @id

Vous pouvez utiliser cette méthode en conjonction avec la procédure stockée qui ajoute l'entrée et ont deux mondes.

Enfin, votre méthode de déclenchement fonctionnerait aussi bien. Il est une alternative à la vue indexée où vous faites la mise à jour vous-même sur une table instad de SQL faire automatiquement. Il est également similaire à l'option précédente où vous déplacez la mise à jour globale de la procédure stockée et un élément déclencheur.

Les trois dernières options, il est plus difficile de gérer la situation quand une entrée est supprimée, mais si ce n'est pas une caractéristique de votre application, vous ne pouvez pas à vous soucier de cela.

Maintenant que vous avez matérialisé, les données en temps réel dans votre base de données maintenant vous pouvez générer dynamiquement votre rapport. Ensuite, vous pouvez ajouter de fantaisie avec AJAX.

Autres conseils

Si elles sont vraiment des problèmes de performances en raison de de nombreux hits de la base de données alors je vous suggère de prendre toutes les entrées et fourrer dans une file d'attente de messages (MSMQ). Ensuite, vous pouvez avoir un service à l'autre bout qui capte les messages et fait une insertion en bloc des données. De cette façon, vous avez moins de coups db. Ensuite, vous pouvez produire dans le fichier texte sur la mise à jour aussi.

Je voudrais créer un tableau récapitulatif qui est enroulé une fois / heure ou la nuit qui calcule miles COMPTEUR. Pour les demandes individuelles que vous pouvez tirer de la table sommaire tous les soirs ainsi que des miles supplémentaires pour journalisés la période entre le dernier calcul de Rollup et lorsque l'utilisateur consulte la page pour obtenir le total pour cet utilisateur.

Combien d'utilisateurs parlez-vous et le nombre d'enregistrements journal par jour?

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