2010-07-16 6 views
3

Je fais une requête simple sur la base de données, une recherche sur deux colonnes. J'ai un index sur les colonnes. Lorsque je fais la recherche dans SQL Server Management Studio, il faut seulement quelques millisecondes pour terminer (toujours moins de 10). Lorsque je fais la même requête dans NHibernate, cela prend plus de 30 secondes. J'ai profilé la requête, et le SQL généré est bien. J'utilise NHibernate Profiler, et quand je sélectionne "Afficher les résultats de la requête" dans NHibernate Profiler, il faut moins d'une seconde pour obtenir les résultats. Où vais-je déballer ici?Comment déboguer une requête NHibernate Select lente?

EDIT: Donc, j'ai décidé de le faire en utilisant session.CreateSQLQuery(), et ça marche très vite. Pourquoi serait-ce plus rapide que l'autre méthode?

EDIT: Il semble que l'utilisation de paramètres de requête pose problème. J'ai créé une requête HQL sans paramètres, et ça allait. Dès que j'ai ajouté les paramètres nommés, le temps d'exécution des requêtes a augmenté considérablement.

TABLE SCHEMA:

CREATE TABLE [dbo].[CRDefendant](
[Id] [int] NOT NULL, 
[FirstName] [varchar](30) NULL, 
[LastName] [varchar](30) NULL, 
[MiddleName] [varchar](30) NULL, 
[Race] [char](1) NULL, 
[Sex] [char](1) NULL, 
[BirthDate] [char](10) NULL, 
[Social] [int] NULL, 
[BadData] [varchar](50) NULL, 
CONSTRAINT [PK__CRDefend__3214EC073B95D2F1] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [GROUP3] 
) ON [GROUP3] 

GO 

QUERY:

SELECT this_.Id as Id16_0_, this_.FirstName as FirstName16_0_, this_.LastName as LastName16_0_, this_.MiddleName as MiddleName16_0_, this_.Race as Race16_0_, this_.Sex as Sex16_0_, this_.BirthDate as BirthDate16_0_, this_.Social as Social16_0_, this_.BadData as BadData16_0_ FROM [CRDefendant] this_ WHERE this_.LastName = @p0 and this_.FirstName like @p1 

INDEX:

CREATE INDEX IX_CRDefendant_Name_DOB 
ON CRDefendant (LastName ASC, FirstName ASC, BirthDate ASC) 
INCLUDE (MiddleName, Race, Sex, Social) 
ON GROUP3 

Répondre

4

Pour commencer, publier la dernière requête présentée par le profileur et la requête que vous exécutez dans SSMS. Ne vous offusquez pas, mais ce qui vous semble «bien» peut révéler une mine d'informations à un œil averti. Ensuite, postez le schéma exact de vos tables, y compris tous les index.

Un exemple de problème possible pourrait être contrainte nvarchar en raison de datatype precedence (un prédicat de recherche avec un nvarchar @variable sur un indice varchar sera dans les résultats d'une analyse complète). En ce qui concerne la question plus générale, comment aborder une telle question, la réponse est: appliquer une méthode comme Waits and Queues. Toutes les informations dont vous avez besoin sont disponibles dans divers DMV comme sys.dm_exec_query_stats, sys.dm_exec_requests, sys.dm_db_index_usage_stats. Le plan d'exécution révèle également beaucoup de choses sur ce qui se passe, mais il est beaucoup plus difficile d'interpréter correctement les informations dans le plan d'exécution.

+0

Eh bien, je l'ai exécuté exactement la requête indiquée dans le profileur dans SSMS et il effectue de manière identique à ma requête manuscrite. –

+0

J'ai modifié la question avec plus d'informations sur les paramètres de requête. –

+1

Effectuez une requête comme indiqué par le profileur, le schéma de la table et l'index –

-1

Comment créez-vous votre requête, avec HQL ou le framework de critères?

J'ai eu la même situation. L'exécution de la faille SQL par le profileur Nhibernate s'est révélée rapide, mais l'application fonctionnait très lentement. Le passage du framework de critères à HQL a résolu le problème.

Je pense qu'il existe un bug/une caractéristique de la structure des critères qui la rend vraiment lente dans certaines circonstances.

+0

Quelles sont ces circonstances? – mynkow

+0

Je l'ai eu dans une variété de ceux. Je n'ai jamais précisé exactement ce qui le causait. Juste dire que j'ai eu exactement le même problème que le PO et cela l'a corrigé. C'est une chose facile à essayer. – Alistair

1

En plus de Remus réponse (qui porte sur le traitement des idiotes (n) varchar par NHibernate), j'ajouter la colonne BadData à inclure la clause trop