我正在对数据库进行简单查询,搜索两列。我有一个列的索引。当我在SQL Server Management Studio中进行搜索时,只需几毫秒即可完成(始终小于10)。当我在NHibernate中执行相同的查询时,它需要超过30秒。我已经分析了查询,生成的SQL很好。我正在使用NHibernate Profiler,当我在NHibernate Profiler中选择“显示查询结果”时,获取结果只需不到一秒钟。我在哪里调试这个?
编辑:所以,我决定使用session.CreateSQLQuery()来做这件事,它的工作速度非常快。为什么这比其他方法更快?编辑:似乎使用查询参数是问题所在。我创建了一个没有参数的HQL查询,它很好。一旦我添加了命名参数,查询执行时间就会大大增加。
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
答案 0 :(得分:4)
首先,发布探查器显示的确切查询以及您在SSMS中运行的查询。没有冒犯,但看起来“好”的东西可能会让训练有素的眼睛看到丰富的信息。其次,发布表的确切模式,包括所有索引。
可能问题的一个例子可能是datatype precedence导致的nvarchar强制(nvarchar
索引上带有varchar
@variable的搜索谓词将导致完整扫描。
至于更一般的问题,如何处理这样的问题,答案是:应用像Waits and Queues这样的方法。您需要的所有信息都可以在各种DMV中使用,例如sys.dm_exec_query_stats
,sys.dm_exec_requests
,sys.dm_db_index_usage_stats
。执行计划还揭示了许多正在发生的事情,但正确地解释执行计划中的信息要困难得多。
答案 1 :(得分:1)
除了Remus的答案(通过nHibernate处理(n)varchar的愚蠢处理),我还将列BadData
添加到INCLUDE子句中
答案 2 :(得分:-1)
您是如何使用HQL或标准框架创建查询的?
我遇到了同样的情况。由Nhibernate profiler运行SQL吐出很快,但应用程序运行速度非常慢。从标准框架切换到HQL解决了这个问题。
我认为标准框架存在一个错误/特征,在某些情况下它会非常慢。