2011-01-31 6 views
1

Je reçois l'exception du délai d'attente NHibernate suivante:NHibernate calendrier de requête sur

could not execute query 

avec le message d'exception interne étant:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 

Ceci est le code NHibernate qui échoue:

shareClassReturns = _session.CreateCriteria<ShareClassTrailingReturn>() 
     .Add(LambdaSubquery.Property<ShareClassTrailingReturn>(x => x.ShareClass.Id).In(GetAvailableShareClassIds())) 
     .Add(LambdaSubquery.Property<ShareClassTrailingReturn>(x => x.ShareClass.Id).In(GetShareclassIdsInCalculationGroup(peerGroups, classificationTypes))) 
     .Add<ShareClassTrailingReturn>(c => c.CurrencyId == "GBP") 
     .AddShareClassReturnOrder(order) 
     .CreateCriteria<ShareClassTrailingReturn>(scr => scr.ShareClass, JoinType.InnerJoin) 
     .Add(ApplicableIdentifiers(searchExpression)) 
     .AddShareClassOrder(order) 
     .SetMaxResults(pageSize) 
     .List<ShareClassTrailingReturn>(); 

Ceci est le SQL que je vois via NHibernate Profiler (bien que je l'ai mis un peu en place, et remplacé tous les articles que je suis avec la sélection select top 25 * pour le rendre plus lisible):

SELECT top 25 * 
FROM  offline.ShareClassTrailingReturn this_ 
     inner join ShareManager.ShareClass shareclass1_ 
      on this_.SCTR_ShareClassId = shareclass1_.ShareClass_Id 
     left outer join DCS.ShareClassInfo shareclass1_1_ 
      on shareclass1_.ShareClass_Id = shareclass1_1_.[ShareClassInfo_MSShareClassId] 
WHERE  
    this_.SCTR_ShareClassId in 
    (
     SELECT this_0_.[Fund_ID] as y0_ 
     FROM dbo.Fund this_0_ 
      inner join CAP.DataUniverse datauniver1_ 
       on this_0_.[Fund_TypeID] = datauniver1_.[DataUniverse_TypeId] 
       and this_0_.[Fund_CountryID] = datauniver1_.[DataUniverse_CountryID] 
     WHERE datauniver1_.[DataUniverse_SiteId] = 100 /* @p0 */ 
    ) 
    and this_.SCTR_ShareClassId in 
    (
     SELECT this_0_.ShareClass_Id as y0_ 
     FROM dbo.vCalculationGroup this_0_ 
     WHERE 
      this_0_.PeerGroupId in (1,8) 
      and this_0_.ClassificationId in (7,1) 
    ) 
    and this_.SCTR_CurrencyId = 'GBP' 
    and 
    (
     shareclass1_.ShareClass_MEX like '%axa%' 
     or shareclass1_.ShareClass_SEDOL like '%axa%' 
     or shareclass1_1_.ShareClassInfo_RIC like '%axa%' 
     or shareclass1_.ShareClass_ISIN like '%axa%' 
     or shareclass1_.ShareClass_CUSIP like '%axa%' 
    ) 
ORDER BY shareclass1_.ShareClass_Name asc 

Si je change les critères NHibernate afin qu'il ne fait pas la sélection contre le vCalculationGroup, à savoir si je supprimer cette ligne:

.Add(LambdaSubquery.Property<ShareClassTrailingReturn>(x => x.ShareClass.Id).In(GetShareclassIdsInCalculationGroup(peerGroups, classificationTypes))) 

ou cela de la SQL

and this_.SCTR_ShareClassId in 
    (
     SELECT this_0_.ShareClass_Id as y0_ 
     FROM dbo.vCalculationGroup this_0_ 
     WHERE 
      this_0_.PeerGroupId in (1,8) 
      and this_0_.ClassificationId in (7,1) 
    ) 

la requête ne fois plus sur. Est-ce que cela signifie que je dois faire quelque chose avec cette vue? Comme l'indexation ou quelque chose?

Quelqu'un pourrait-il suggérer comment je peux aborder la résolution de ce problème?

Modifier: Je dois ajouter que la requête s'exécute correctement à partir de SQL Server Management Studio et revient après environ 6 secondes. Bien que cela dit, quand je regarde le plan d'exécution, il signale qu'il y a un Index manquant sur offline.ShareClassTrailingReturn. Est-il probable que cela pourrait être le problème?

Répondre

0

Je voudrais vraiment jeter un oeil à l'indexation sur la vue si le retrait de cette partie fait mieux fonctionner. Il serait également intéressant de vérifier votre délai de connexion dans votre application. Si vous dites que cela fonctionne correctement dans Management Studio en six secondes, il se peut que le délai d'expiration de la connexion de votre application soit inférieur à six secondes (ou la valeur par défaut est inférieure). Ce serait un bon point de départ.

Il vaut la peine d'essayer d'éviter un grand nombre de sous-requêtes imbriquées en général. Vous avez beaucoup dans le SQL qui est produit. Parfois, il est plus efficace d'écrire le SQL ou HQL vous-même, au lieu d'utiliser beaucoup de jointures complexes dans les API de Criteria ou Linq NHibernate. Vous êtes plus susceptible de produire du SQL efficace pour le travail!

+0

Bon conseil, merci. Nous avons résolu ceci en faisant des jointures plutôt que des 'In <>()' s – DaveDev