0
votes

La requête fonctionne bien en deuxième exécution, mais prend trop de temps en première exécution

J'écris une requête qui accepte une chaîne séparée par des virgules et calculant la somme de la transaction. Ce qui fonctionne bien comme le résultat sage, mais en prenant trop de temps pour exécuter à la première tentative. Je comprends que son besoin de réglage, mais je n'ai pas découvert que la raison exacte ne peut-être qu'aucune ne peut me dire ce qui va mal avec ma requête.

Declare @IDs nvarchar(max)='1,4,5,6,8,9,43,183'

SELECT isnull(isnull(SUM(FT.PaidAmt),0) - isnull(SUM(CT.PaidAmt),0),0) [Amount], convert(char(10),FT.TranDate,126) [Date]
from FeeTransaction FT
Inner Join (
    Select max(P.Id) [Id], P.TranMainId, isnull(SUM(P.AmtToPay),0) [Amt]
    From Patient_Account P
    Group By P.TranMainId
) PA ON FT.Id = PA.TranMainId
Inner Join Patient_Account XP ON PA.Id = XP.Id
Inner Join Master_Fee MF ON XP.FeeId = MF.Id
INNER Join Master_Patient MP ON FT.PID = MP.Id
Inner Join Master_FeeType TY ON MF.FeeTypeId = TY.Id
Left JOIN FeeTransaction CT on FT.TransactionId = CT.TransactionId AND CT.TranDate between '2019'+'08'+'01' and '2019'+'08'+'31' and CT.[Status] <> 'A' AND isnull(CT.IsCancel,0) = 1
Where convert(nvarchar,FT.TranDate,112) between '2019'+'08'+'01' and '2019'+'08'+'31' AND FT.[Status] = 'A' AND XP.FeeId in (SELECT val FROM dbo.f_split(@IDs, ','))
AND isnull(FT.IsCancel,0) = 0 AND FT.EntryBy = 'rajan'
Group By convert(char(10),FT.TranDate,126)


4 commentaires

Conversion d'une date à une chaîne de votre lieu où la clause est mauvaise, SQL Server ne peut pas utiliser l'index, et vous utilisez entre sur les chaînes au lieu des dates. Laissez le champ de date tel qu'il est et utilisez les dates des valeurs entre les valeurs performantes.


SQL Monitor peut vous montrer beaucoup de détails sur les caractéristiques générales d'exécution de la requête.


Et affichez votre plan d'exécution.


Si la première exécution (après un long délai) est lente, les exécutions suivantes sont rapidement rapides (ER), alors SQL supplémentaires comporte moins de RAM que optimale et votre requête provoque beaucoup d'accès au disque. Comme les autres personnes ont dit, analysez le plan d'exécution de la requête, reportez-vous à votre requête pour utiliser des index appropriés, etc. De cette façon, vous pouvez réduire considérablement l'accès du disque.


3 Réponses :


0
votes

Je reformulerais la requête un peu: xxx

puis pour cette version, vous spécifiquement un index sur fetransaction (entrée, statut, trandate, annulez) .

Notez les modifications suivantes:

  • Vous n'avez pas besoin d'agréger patient_accompagnant comme sous-requête. Les fonctions de fenêtre sont assez pratiques.
  • Vos comparaisons de date excluent l'utilisation d'index. La conversion des dates en cordes est une mauvaise pratique en général.
  • vous avez sur-utilisé isnull () .
  • Je suppose que les index appropriés sont en place pour les jointures.

0 commentaires

0
votes

J'utiliserais string_split et des expressions de table communes et éliminez les conversions de date: xxx


0 commentaires

0
votes

Non seulement votre requête est lente, mais il semble que cela donne une sortie incorrecte.

i) Lorsque vous n'utilisez aucune colonne de patient_account dans votre RESUNTSE Alors pourquoi écrivez-vous cette sous-requête? xxx

ii) Évitez d'utiliser <> .so statut doit être 'a' ou 'i' Donc, écrivez cela à la place ct. [Statut] = 'i'

iii) Quel est le type de données correct de trandate? Ne pas utiliser la fonction dans la condition. .

iv) Pas besoin de isnull (ct.iscanque, 0) = 1 , écrivez plutôt ct.iscanqued = 1 < P> Mon script est donc simplement un terme, mais il est facile de comprendre. xxx


0 commentaires