2
votes

Dois-je appliquer le comptage dans DB ou dans Code?

J'ai le code suivant où j'essaie d'obtenir le nombre de lignes dans le même ensemble de données avec différentes correspondances.

Ma question est de savoir si dois-je obtenir le décompte en code C # avec un IEnumerable ou en interrogeant un IQueryable à partir de la base de données?

Laquelle est la plus efficace, les transactions de base de données multiples ou le filtrage et le comptage IEnumerable ?

public List<Tuple<string, int>> CalismaVeIzinleriHesapla(long personelId, DateTime baslangic, DateTime bitis)
{
    var hesaplamalar = new List<Tuple<string, int>>();
    var puantajList = puantajlar.Where(p => p.PersonelId == personelId && (p.Tarih >= baslangic && p.Tarih <= bitis));

    var haftaTatili = puantajList.Where(p => p.Secenek.Deger == "Ht").Count();
    var resmiTatil = puantajList.Where(p => p.Secenek.Deger == "Rt").Count();
    var yillikIzin = puantajList.Where(p => p.Secenek.Deger == "Yi").Count();
    var odenecekRapor = puantajList.Where(p => p.Secenek.Deger == "R+").Count();
    var dogumIzni = puantajList.Where(p => p.Secenek.Deger == "Di").Count();
    var olumIzni = puantajList.Where(p => p.Secenek.Deger == "Öi").Count();
    var evlilikIzni = puantajList.Where(p => p.Secenek.Deger == "Ei").Count();
    var odenmeyecekRapor = puantajList.Where(p => p.Secenek.Deger == "R-").Count();
    var ucretsizIzin = puantajList.Where(p => p.Secenek.Deger == "Ãœi").Count();
    var devamsizlik = puantajList.Where(p => p.Secenek.Deger == "D").Count(); 

    return hesaplamalar;
}


1 commentaires

En vérité, vous n'avez techniquement pas besoin de vous en préoccuper. Si vous comptez un IQueryable , il ira intelligemment soit dans la base de données si le résultat n'est pas présent, soit en mémoire si c'est le cas.


3 Réponses :


2
votes

Ma question est de savoir si dois-je obtenir le décompte en code C # avec un IEnumarable ou en interrogeant un IQueryable dans DB

Si vous n'avez besoin que du nombre de lignes, le décompte doit être effectué dans la base de données, pas en mémoire. Si vous comptez en mémoire en tirant la liste de données de la base de données vers la mémoire, cela gaspillera inutilement la mémoire de votre serveur et coûtera des performances.


3 commentaires

Je ne suis pas principalement préoccupé par la mémoire car les données ne sont pas énormes. Donc, vous dites que même si chaque comptage est une transaction supplémentaire à partir de la base de données, le comptage en mémoire serait plus lent?


@ brainoverflow98 Événement si vous le faites en mémoire, vous devez à chaque fois effectuer une transaction dans la base de données pour extraire des données. N'est-ce pas ?. Je préfère donc toujours compter sur la base de données plutôt que de tirer inutilement de la mémoire, que l'ensemble de données soit volumineux ou non.


Je pense que je pourrais tout faire dans les transactions onc pour récupérer les données dont j'ai besoin en mémoire. Quoi qu'il en soit, la réponse fournie par @amd est plutôt sympa. Merci d'avoir répondu :)



4
votes

Quant à votre cas, l'interrogation et le comptage dans la base de données sont plus efficaces. quelque chose comme ça serait efficace.

puantajlar
  .Where(p => p.PersonelId == personelId && (p.Tarih >= baslangic && p.Tarih <= bitis))
  .GroupBy(x => x.Secenek.Deger)
  .Select(group => new { group.Key, Count = group.Count()  })


3 commentaires

Dans quel genre de scénario compter de mémoire serait plus efficace? Si je ne pouvais pas le gérer en une seule transaction, serait-il préférable de les compter en mémoire? Quelle est la limite entre la complexité et les performances SQL? Je sais que c'est beaucoup mais je suis toujours confus par ces décisions :)


1) Toujours opter pour la base de données sauf si vous ne pouvez pas 2) Si vous avez déjà récupéré les enregistrements (pour d'autres raisons), les compter en mémoire est tout à fait acceptable


@amd ma situation ressemble plus à la seconde où j'ai déjà récupéré l'ensemble de données dans les méthodes précédentes afin que je puisse utiliser le même pour ces fonctions. Merci :)



1
votes

Complexité et performance, les deux dépendent de votre situation, s'il n'y a pas de données volumineuses, la performance importe peu, mais parfois vous devez prendre une décision en fonction de votre situation. En exécutant votre code, il doit se connecter à DB et exécuter la requête count dans chaque ligne de code il est clair à 100% que compter les mêmes lignes dans DB est plus efficace en une seule prise de vue, vous pouvez donc faire quelque chose comme:

puantajlar
  .Where(p => p.PersonelId == personelId && (p.Tarih >= baslangic && p.Tarih <= bitis))
  .GroupBy(x => x.Secenek.Deger)
  .Select(group => new { group.Key, Count = group.Count()  })

ou vous pouvez le faire de manière plus efficace en les regroupant en une seule shoot aussi comme @amd mentionné:

select p.Secenek.Deger,
....
sum(case when p.Secenek.Deger = 'Ht' then 1 else 0 end) haftaTatili,
sum(case when p.Secenek.Deger = 'Rt' then 1 else 0 end) resmiTatil
.....
from puantajlar p
group by p.Secenek.Deger


2 commentaires

Donc, vous dites d'une manière ou d'une autre que je ne devrais pas appliquer des opérations à un ensemble de données en mémoire?


L'application de la requête avec dataset ou autre chose comme EF n'est pas importante car la façon dont votre code doit s'exécuter, enfin vous devez utiliser un ORM pour accéder aux champs de comptage soit ensemble de données ou quelque chose, mais c'est important comment la requête doit être exécutée, une par une ou toutes dans une seule requête.