简体   繁体   English

为什么此hql比使用标准快得多?

[英]Why is this hql so much faster than using criteria?

I'm using nhibernate as ORM. 我正在使用nhibernate作为ORM。 And one of my selections is incredible slow. 我的选择之一是令人难以置信的缓慢。 The thing is, that it takes a long time to generate the sql. 事实是,生成sql需要很长时间。 I'm sure it's not the sql query itself that's slow, because I timed the query itself with sql profiler. 我确信不是SQL查询本身很慢,因为我使用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. 结果表明,从开始执行nhibernate代码到将查询实际发送到db之间有大约15秒的间隔。 The generated SQL query itself is as fast as I'd expect it to be. 生成的SQL查询本身的速度与我期望的一样快。

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) 但是,它们的执行性能几乎相同(速度很慢,例如生成SQL查询需要15秒)

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. 我真的很想使用linq到nhibernate版本。 Any idea why the code performs differently? 知道为什么代码的性能不同吗? (If you need more details, just ask!) (如果您需要更多详细信息,请询问!)

Edit1 编辑1

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. 哦,老兄,我犯了一个愚蠢的错误还是什么?我在sql profiler中错误地读了错误的列。嗯,前两个的实际执行时间是〜18秒,第三个是〜0秒。 I'm trying to find the differences in sql atm... 我正在尝试查找sql​​ atm中的差异...

Edit2 编辑2

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" 产生的查询几乎完全相同,除了前两个都包装在“ 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? 有类似的经历吗?

They actually generate different sql. 它们实际上生成不同的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 (简体)生成的SQL

Fast version: 快速版本:

SELECT Id, Name FROM documents WHERE StorageType = 'D'

Slow version (both linq and criteria)(typing from memory atm, will check later): 慢速版本(linq和条件)(从内存atm键入,稍后将检查):

sp_execsql N'SELECT Id, Name FROM documents WHERE StorageType = @p0', N'@p0 nchar(1)', N'D'

note that 'StorageType' is of type varchar(1). 请注意,“ StorageType”的类型为varchar(1)。 This blog post explains why this is slow 这篇博客文章解释了为什么这么慢

The problem here is that @p0 is passed as NCHAR(1) (aka a Unicode char) which does not match the index of the column with is non-Unicode. 这里的问题是@ p0作为NCHAR(1)(也称为Unicode字符)传递,该列与非Unicode索引不匹配。 This cases the index scan. 这种情况下索引扫描。

Apparently, an index scan takes about 17 secs on this table. 显然,对该表进行索引扫描大约需要17秒。

They are different paths in NHibernate to get the same data. 它们是NHibernate中获取相同数据的不同路径。 They construct the queries using different code. 他们使用不同的代码构造查询。 There are discussions about the problem with NHibernate's linq provider. 关于NHibernate的linq提供程序存在问题的讨论。 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. 最后,我编写了自己的LINQ提供程序,以将LINQ提供给NHibernate,后者在第二个示例中仅创建了字符串,然后使用该字符串来获取数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM