为什么这个 hql 比使用 criteria 快得多?
我使用 nhibernate 作为 ORM。我的选择之一慢得令人难以置信。问题是,生成sql需要很长时间。我确信不是 sql 查询本身很慢,因为我使用 sql profiler 对查询本身进行了计时。它表明,开始执行 nhibernate 代码和查询实际发送到数据库之间有约 15 秒的间隙。生成的 SQL 查询本身与我预期的一样快。
选择代码(在存储库中)如下
public IEnumerable<Document> GetAllDocumentsReadyForDeletion()
{
return from doc in _session.Query<Document>()
where doc.StorageType == 'D'
select doc;
}
我也尝试过:
return _session.CreateCriteria<Document>()
.Add(Restrictions.Eq("StorageType", 'D'))
.List<Document>();
这是等效的(对吗?)。然而,它们的执行速度大致相同(很慢,比如生成 sql 查询需要 15 秒)
但是,执行速度与我想要的一样快,我不知道为什么:
return _session.CreateQuery(
"from Document doc where doc.StorageType = 'D'")
.List<Document>();
我真的想使用 linq to nhibernate 版本。知道为什么代码表现不同吗? (如果您需要更多详细信息,请询问!)
Edit1
天哪,我犯了一个愚蠢的错误还是什么..我错误地在sql分析器中读取了错误的列..嗯,实际执行时间前两个约为 18 秒,第三个约为 0 秒。我试图找到 sql atm 中的差异...
Edit2
这实际上变成了一个完全不同的问题。生成的查询几乎完全相同,除了前两个查询被包装在“exec sp_executesql”中。
现在我用查询分析器对此进行了跟踪,慢速查询有一个步骤:
clustered index scan.
快速查询有两个步骤:
Index seek
Bookmark lookup
有类似的经历吗?
I'm using nhibernate as ORM. And one of my selections is incredible slow. The thing is, that it takes a long time to generate the sql. I'm sure it's not the sql query itself that's slow, because I timed the query itself with sql profiler. And it showed that there is a ~15 sec gap between starting to execute the nhibernate code, and the query being actually sent to the db. The generated SQL query itself is as fast as I'd expect it to be.
The selection code (in a repository) is as follows
public IEnumerable<Document> GetAllDocumentsReadyForDeletion()
{
return from doc in _session.Query<Document>()
where doc.StorageType == 'D'
select doc;
}
I also tried:
return _session.CreateCriteria<Document>()
.Add(Restrictions.Eq("StorageType", 'D'))
.List<Document>();
wich is the equivalent (right?). However, they both perform about the same (slow, like 15 secs to generate the sql query)
This however, performs as fast as I want it to be, and I have no clue why:
return _session.CreateQuery(
"from Document doc where doc.StorageType = 'D'")
.List<Document>();
I really want to use the linq to nhibernate version. Any idea why the code performs differently? (If you need more details, just ask!)
Edit1
Oh man, did I make a stupid mistake or what.. I mistakenly read the wrong column in the sql profiler.. The ehm, actual execution time for the first two are ~18 seconds, the 3rd is ~0 secs. I'm trying to find the differences in sql atm...
Edit2
This is actually becoming a whole different question. The resulting queries are almost exactly the same, except for that the first two are wrapped inside a "exec sp_executesql"
Now I've traced this a bit with query analyser, and the slow query has one step:
clustered index scan.
The fast query has two steps:
Index seek
Bookmark lookup
Any experiences with something like this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
他们实际上生成不同的sql。其中之一使用索引,而其中之一则不使用索引。这就是原因。为什么其中一个使用索引而另一个不使用下一个问题。
(简化)生成的 SQL
快速版本:
慢速版本(linq 和 criteria)(从内存 atm 键入,稍后检查):
注意“StorageType”的类型为 varchar(1)。 这篇博客文章解释了为什么速度很慢
显然,对该表进行索引扫描大约需要 17 秒。
They actually generate different sql. One of wich uses the index, and one of wich doesn't. That's why. Why one of those uses the index and the other doesn't is content for a next question.
(Simplified) Generated SQL
Fast version:
Slow version (both linq and criteria)(typing from memory atm, will check later):
note that 'StorageType' is of type varchar(1). This blog post explains why this is slow
Apparently, an index scan takes about 17 secs on this table.
它们是 NHibernate 中获取相同数据的不同路径。他们使用不同的代码构建查询。关于 NHibernate 的 linq 提供程序的问题进行了讨论。我最终编写了自己的 LINQ 提供程序,为我提供了 NHibernate 的 LINQ,它仅在第二个示例中创建字符串,然后使用它来获取数据。
They are different paths in NHibernate to get the same data. They construct the queries using different code. There are discussions about the problem with NHibernate's linq provider. I ended up writing my own LINQ provider to give me LINQ into NHibernate that just creates the string in the second example then uses that to get the data.