2014-01-15 133 views
0

以下是花的时间过长 -LINQ查询是需要长时间

using (var db = new Agreements_DBEntities()) 
{ 

    bool isProfileExist = (from ua in db.UserAgreementDetails 
            where ua.uID == uID && 
              ua.uMailId == uMailId && 
              ua.uType == uType && 
              ua.UProfile.HasValue && ua.UProfile.Value 
            select true).Any(); 
} 

上面一行bool isProfileExist时间过长....什么是错的呢?

+4

这是什么意思'太久'? “多久”可以接受? **生成的SQL查询是什么?**你有索引吗? SQL Server端的执行计划是什么样的?这是一个“冷”查询,还是至少已经执行过一次? –

回答

1

嗯,我想你可以删除where条款并直接使用Any(我不知道该IQueryable的提供者将如何优化LINQ),以及你如何标杆,但:

db.UserAgreementDetails.Any(ua => ua.uID == uID && 
              ua.uMailId == uMailId && 
              ua.uType == uType && 
              ua.UProfile.HasValue && ua.UProfile.Value); 

即使这样, db中有多少行?这是查询执行的第一次,等等。?

+0

不会生成相同的查询吗? – wudzik

+0

@wudzik取决于供应商我认为 –

+0

也许'Any'会删除他之前的选择和投影。但我现在无法测试它。 –

1

首先要做的是检查生成的实际查询。 SQLServer Profiler非常适合这种情况,其他数据库有其他查询日志记录方法。

可能有更好的SQL生成,如果我们简化了您的查询的不必要位:

bool isProfileExist = db.UserAgreementDetails.Any(
    ua => ua.uID == uID && 
    ua.uMailId == uMailId && 
    ua.uType == uType && 
    ua.UProfile.HasValue && 
    ua.UProfile.Value); 

我想这将产生几乎相同的代码,但它可能不是,它的价值试着查询提供者是否给了一些奇怪的东西

之后,我猜(但不能确定)主要的罪魁祸首实际上是数据库服务器。检查您是否有一个索引或一组索引,以便快速执行此查询。

的想法指数很可能是一个涵盖对应uIDuMailIduTypeUProfile,或一个包括一些那些和“具有”其他的列。但是,我们不需要孤立地考虑这个查询,因此您可能会决定在它们上面使用单独的索引,或者仅仅覆盖某些索引的索引就会这样做:特别是,如果只有少量行具有相同的uID,那么只需要做一个索引就可以完成这项工作,而不会增加很多插入成本,并且也会使更多的其他查询受益。