【问题标题】:How do I debug slow NHibernate Select query?如何调试慢 NHibernate Select 查询?
【发布时间】:2011-03-16 18:24:33
【问题描述】:

我正在对数据库进行简单查询,搜索两列。我在列上有一个索引。当我在 SQL Server Management Studio 中进行搜索时,只需几毫秒即可完成(总是少于 10 毫秒)。当我在 NHibernate 中执行相同的查询时,需要 30 多秒。我已经分析了查询,生成的 SQL 很好。我正在使用 NHibernate Profiler,当我在 NHibernate Profiler 中选择“显示查询结果”时,只需不到一秒钟的时间即可获得结果。我该从哪里调试这个?

编辑:所以,我决定使用 session.CreateSQLQuery() 来执行此操作,它运行得非常快。为什么这会比其他方法更快?

编辑:似乎使用查询参数是问题所在。我创建了一个没有参数的 HQL 查询,这很好。一旦我添加了命名参数,查询执行时间就会急剧增加。

表格架构:

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

查询:

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

索引:

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

【问题讨论】:

    标签: sql-server nhibernate fluent-nhibernate


    【解决方案1】:

    除了 Remus 的回答(解决了 nHibernate 对 (n)varchar 的白痴处理)之外,我还将 BadData 列添加到 INCLUDE 子句中

    【讨论】:

      【解决方案2】:

      您是如何使用 HQL 或条件框架创建查询的?

      我也遇到过同样的情况。运行 Nhibernate 分析器吐出的 SQL 速度很快,但应用程序运行速度非常慢。从标准框架切换到 HQL 解决了这个问题。

      我认为标准框架的一个错误/功能使其在某些情况下变得非常缓慢。

      【讨论】:

      • 这些是什么情况?
      • 我已经用过很多次了。我从来没有准确地指出是什么原因造成的。只是说我遇到了与 OP 完全相同的问题,这解决了它。这很容易尝试。
      【解决方案3】:

      首先,发布探查器显示的确切查询以及您在 SSMS 中运行的查询。无意冒犯,但对您来说看起来“不错”的东西可能会向训练有素的眼睛揭示大量信息。其次,发布表的确切架构,包括所有索引。

      一个可能的问题示例可能是由于datatype precedence 导致的nvarchar 强制(在varchar 索引上带有nvarchar @variable 的搜索谓词将导致完全扫描)。

      至于更普遍的问题,如何解决这样的问题,答案是:应用类似Waits and Queues 的方法。您需要的所有信息都可以在各种 DMV 中找到,例如 sys.dm_exec_query_statssys.dm_exec_requestssys.dm_db_index_usage_stats。执行计划还揭示了很多关于正在发生的事情,但要正确解释执行计划中的信息要困难得多。

      【讨论】:

      • 好吧,我已经完全运行了 SSMS 分析器中显示的查询,它的执行与我的手写查询相同。
      • 我已经编辑了问题,提供了有关查询参数的更多信息。
      • 通过分析器、表的模式和索引显示的查询
      • 您的回答让我找到了解决方案。我正在使用 Fluent NHibernate 并将 varchar 映射为 nvarchar (显然)。所以我覆盖了映射以使用 CustomType("AnsiString") 并解决了问题。
      猜你喜欢
      • 2023-03-14
      • 2021-07-06
      • 2016-01-10
      • 2020-12-25
      • 2016-11-23
      • 1970-01-01
      • 2015-07-30
      • 2012-04-18
      • 2012-05-04
      相关资源
      最近更新 更多