Nhibernate查询超时而sql查询没有

时间:2013-08-14 11:53:23

标签: c# sql sql-server nhibernate

我正在运行此代码来获取数据:

var docs = session.Query<Content>().Where(x =>  x.Attachments.Count > 0).Skip(pageNumber * Pagesize).Take(count).ToList();

它应该获得带附件的所有文件。我添加了分页来提升它,而不是一步完成所有文档(大约有10k文档匹配,全部是600k)。

由NHibernate执行的查询:

exec sp_executesql N'SELECT TOP (@p0) CastleId12_, Version12_, Abstract12_, Publishe4_12_, Title12_, Body12_, Brand12_, Source12_, SourceCo9_12_, IdInSource12_, Documen11_12_, HTML12_, Subscri13_12_, FileLoc14_12_, OtherMe15_12_, Companies12_, Keywords12_, Subscri18_12_, Author12_, Documen20_12_, SourceF21_12_, SourceB22_12_, UpdateDate12_, SourceU24_12_, Content25_12_, Interna26_12_, Workben27_12_, Checksum12_, Field29_12_ FROM (select content0_.CastleId as CastleId12_, content0_.Version as Version12_, content0_.Abstract as Abstract12_, content0_.PublishedDate as Publishe4_12_, content0_.Title as Title12_, content0_.Body as Body12_, content0_.Brand as Brand12_, content0_.Source as Source12_, content0_.SourceContentId as SourceCo9_12_, content0_.IdInSource as IdInSource12_, content0_.DocumentType as Documen11_12_, content0_.HTML as HTML12_, content0_.Subscriptions as Subscri13_12_, content0_.FileLocation as FileLoc14_12_, content0_.OtherMetadata as OtherMe15_12_, content0_.Companies as Companies12_, content0_.Keywords as Keywords12_, content0_.SubscriptionUpdateDate as Subscri18_12_, content0_.Author as Author12_, content0_.DocumentStatus as Documen20_12_, content0_.SourceFileExtension as SourceF21_12_, content0_.SourceBaseName as SourceB22_12_, content0_.UpdateDate as UpdateDate12_, content0_.SourceUpdateDate as SourceU24_12_, content0_.ContentUpdateDate as Content25_12_, content0_.InternalDocumentType as Interna26_12_, content0_.WorkbenchList as Workben27_12_, content0_.Checksum as Checksum12_, content0_.Field_id as Field29_12_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row from [Content] content0_ where (select cast(count(*) as INT) from ContentAttachments attachment1_ where content0_.CastleId=attachment1_.DocumentId)>@p1) as query WHERE query.__hibernate_sort_row > @p2 ORDER BY query.__hibernate_sort_row',N'@p0 int,@p1 int,@p2 int',@p0=50,@p1=0,@p2=0

如果我以这种方式运行它,在SSMS中执行需要1.5分钟,当然它会在我的应用程序中抛出超时异常。

如果我将其更改为:

SELECT TOP (50) CastleId12_, Version12_, Abstract12_, Publishe4_12_, Title12_, Body12_, Brand12_, Source12_, SourceCo9_12_, IdInSource12_, Documen11_12_, HTML12_, Subscri13_12_, FileLoc14_12_, OtherMe15_12_, Companies12_, Keywords12_, Subscri18_12_, Author12_, Documen20_12_, SourceF21_12_, SourceB22_12_, UpdateDate12_, SourceU24_12_, Content25_12_, Interna26_12_, Workben27_12_, Checksum12_, Field29_12_ FROM (select content0_.CastleId as CastleId12_, content0_.Version as Version12_, content0_.Abstract as Abstract12_, content0_.PublishedDate as Publishe4_12_, content0_.Title as Title12_, content0_.Body as Body12_, content0_.Brand as Brand12_, content0_.Source as Source12_, content0_.SourceContentId as SourceCo9_12_, content0_.IdInSource as IdInSource12_, content0_.DocumentType as Documen11_12_, content0_.HTML as HTML12_, content0_.Subscriptions as Subscri13_12_, content0_.FileLocation as FileLoc14_12_, content0_.OtherMetadata as OtherMe15_12_, content0_.Companies as Companies12_, content0_.Keywords as Keywords12_, content0_.SubscriptionUpdateDate as Subscri18_12_, content0_.Author as Author12_, content0_.DocumentStatus as Documen20_12_, content0_.SourceFileExtension as SourceF21_12_, content0_.SourceBaseName as SourceB22_12_, content0_.UpdateDate as UpdateDate12_, content0_.SourceUpdateDate as SourceU24_12_, content0_.ContentUpdateDate as Content25_12_, content0_.InternalDocumentType as Interna26_12_, content0_.WorkbenchList as Workben27_12_, content0_.Checksum as Checksum12_, content0_.Field_id as Field29_12_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row from [Content] content0_ where (select cast(count(*) as INT) from ContentAttachments attachment1_ where content0_.CastleId=attachment1_.DocumentId)>0) as query WHERE query.__hibernate_sort_row > 0 ORDER BY query.__hibernate_sort_row 

(唯一的变化是我没有在sp_executesql中运行它并且我在内联参数) 执行大约需要2秒钟。

有谁知道如何修改我的Nhibernate查询以便更快地运行?我尝试更改页面大小和页面,但没有任何改变。我读到了sp_executesql,但我发现的唯一一件事就是varchar个论点:https://stackoverflow.com/a/4540108/1714342

为什么SSMS执行速度这么慢?

2 个答案:

答案 0 :(得分:1)

您可以尝试:

  • 在您的NHibernate查询中设置显式OrderBy(比如在主键上)(因为我猜默认生成的ORDER BY CURRENT_TIMESTAMP对优化器没有帮助)
  • 替换

      .Where(x =>  x.Attachments.Count > 0)
    

      .Where(x =>  x.Attachments.Any())
    

    (我想这会导致生成不同的SQL查询)

答案 1 :(得分:0)

  

它应该获得带附件的所有文件。

我应该建议不要加载所有文档,只需加载文档的基本信息并显示给用户。当用户实际要求您显示数据内容时,请加载该特定文档。