J'ai une table de base avec des transactions et je dois créer une table avec des totaux cumulés. J'ai besoin qu'ils soient par compte et que j'ai également quelques totaux cumulés pour chaque compte (en fonction du type de transaction), et à l'intérieur, certains totaux cumulés par sous-compte.
Ma table de base a ces champs (plus ou moins):
AccountID | SubAccountID | TransactionType | TransactionAmount
Considérant que j'ai environ 4 types de totaux en cours d'exécution par compte / type de transaction et 2 autres totaux en cours d'exécution par compte / sous-compte / type de transaction, et j'ai environ 2 millions de comptes avec environ 10 sous-comptes chacun, et j'obtiens environ 10 000 transactions chaque minute (à charge maximale), comment feriez-vous?
Il est également indispensable que cela s'exécute de manière asynchrone via un travail SQL, créant les agrégations sans faire partie des transactions elles-mêmes.
Je suis assez coincé en utilisant un curseur ici - ce qui prend beaucoup trop de temps. J'apprécierais vraiment tous les conseils / articles qui font plus ou moins la même chose.
la source
Réponses:
Asynchrone implique que les totaux en cours d'exécution n'ont pas besoin d'être complètement précis à tout moment, ou que vos modèles de changement de données sont tels qu'une construction totale unique en cours d'exécution sera valide et précise jusqu'à la prochaine charge. Quoi qu'il en soit, je suis sûr que vous avez réfléchi à cette partie, donc je ne m'attarderai pas sur le sujet.
Vos principales options pour une méthode haute performance prise en charge sont une fonction / procédure SQLCLR ou une
UPDATE
méthode d'itération basée sur des ensembles d'Hugo Kornelis. La méthode SQLCLR (implémentée dans une procédure, mais raisonnablement facile à traduire) peut être trouvée ici .Je n'ai pas pu trouver la méthode d'Hugo en ligne, mais elle est détaillée dans l'excellent MVP Deep Dives (Volume 1). Un exemple de code pour illustrer la méthode d'Hugo (copié à partir de l'un de mes messages sur un autre site pour lequel vous n'avez peut-être pas de connexion) est illustré ci-dessous:
Dans SQL Server 2012, vous pouvez utiliser les extensions de fonction de fenêtrage, par exemple
SUM OVER (ORDER BY)
.la source
Je ne sais pas pourquoi vous voulez asynchrone, mais quelques vues indexées ressemblent juste au ticket ici. Si vous voulez un SUM simple pour un groupe, c'est: définir le total cumulé.
Si vous voulez vraiment asynchrone, avec 160 nouvelles lignes par seconde, vos totaux cumulés seront toujours obsolètes. Asynchrone signifierait aucun déclencheur ou vue indexée
la source
Le calcul des totaux cumulés est notoirement lent, que vous le fassiez avec un curseur ou avec une jointure triangulaire. Il est très tentant de dénormaliser, de stocker les totaux en cours dans une colonne, surtout si vous la sélectionnez fréquemment. Cependant, comme d'habitude lorsque vous dénormalisez, vous devez garantir l'intégrité de vos données dénormalisées. Heureusement, vous pouvez garantir l'intégrité des totaux cumulés avec des contraintes - tant que toutes vos contraintes sont fiables, tous vos totaux cumulés sont corrects.
De cette façon, vous pouvez facilement vous assurer que le solde actuel (totaux cumulés) n'est jamais négatif - l'application par d'autres méthodes peut également être très lente. Le script suivant illustre la technique.
Copié de mon blog
la source