2

我有以下查询:

if (idUO > 0)
{
    query = query.Where(b => b.Product.Center.UO.Id == idUO);
}
else if (dependencyId > 0)
{
    query = query.Where(b => b.DependencyId == dependencyId );
}
else
{
    var dependencyIds = dependencies.Select(d => d.Id).ToList();

    query = query.Where(b => dependencyIds.Contains(b.DependencyId.Value));
}

[...] <- Other filters...

if (specialDateId != 0)
{
    query = query.Where(b => b.SpecialDateId == specialDateId);
}

所以,我在这个查询中有其他过滤器,但最后,我在数据库中处理查询:

return query.OrderBy(b => b.Date).Skip(20 * page).Take(20).ToList(); // the returned object is a Ticket object, that has 23 properties, 5 of them are relationships (FKs) and i fill 3 of these relationships with lazy loading

当我访问第一个page时,它可以,查询不到一个 1 秒,但是当我尝试访问页面 30000 时,查询需要超过 20 秒。linq 查询中有一种方法可以提高查询的性能吗?还是仅在数据库级别?而在数据库层面,对于这种查询,提高性能最好的方法是什么?

4

4 回答 4

2

imo,这里没有太多空间可以让事情变得更好(至少查看提供的代码)。

当您尝试在此类数字上取得良好的性能时,我建议您根本不要使用 LINQ,或者在列表中使用它来访问具有较小数据访问权限的东西。

您可以在这里做的是在DataBase级别上引入该数据的分页,使用 some ,并从您的代码中stored procedure调用它。C#

于 2012-08-31T12:27:24.440 回答
1

1- 在数据库中创建一个视图,按日期对项目进行排序,包括所有相关关系,如产品等。

2-创建一个使用相关参数查询此视图的存储过程。

于 2012-08-31T12:31:35.413 回答
1

我建议您启动 SQL Server Profiler,并在运行查询(快速和慢速)时在服务器上运行配置文件。完成此操作后,您可以将其拉入数据库引擎优化顾问以获取有关应该添加的索引的一些提示。这在过去对我有很大的影响。当然,如果你知道你需要什么索引,你可以在不运行 Advisor 的情况下添加它们 :)

于 2012-08-31T12:35:38.627 回答
0

我想你会发现瓶颈出现在数据库上。这就是为什么;

询问。

你有你的查询和标准。它以非常丑陋但不太糟糕的选择语句进入数据库。

.OrderBy(b => b.Date)

现在您正在按日期订购这个巨大的记录集,这可能不是一个可怕的打击,因为它(希望)在该字段上建立了索引,但这确实意味着整个集合将被放入内存并在任何跳过或采取之前进行排序发生。

.Skip(20 * 页).Take(20)

好的,这就是糟糕的数据库变得粗糙的地方。对于大型记录集,实体在这种事情上非常糟糕。我敢于打开 sql profiler 并查看它发送过来的 sql 的随机混乱。

当您开始跳过和获取时,Entity 通常会发送查询,强制数据库扫描整个巨大的记录集,直到找到您要查找的内容。如果这是记录集中的第一个有序记录,比如第 1 页,它可能不会花费很长时间。当您选择第 30,000 页时,由于 Entity 准备您的声明的方式,它可能正在扫描大量数据。

我强烈建议您查看以下链接。我知道它说的是 2005,但它也适用于 2008。

http://www.codeguru.com/csharp/.net/net_data/article.php/c19611/Paging-in-SQL-Server-2005.htm

阅读该链接后,您可能需要考虑如何创建存储过程来完成您的目标。它将更轻量级,具有缓存的执行计划,并且可以很好地保证为您更快地返回数据。

除此之外,如果您想坚持使用 LINQ,请阅读Compiled Queries并确保将 MergeOption.NoTracking 设置为只读操作。您还应该尝试返回一个带有显式连接的对象查询,而不是一个带有延迟加载的 IQueryable,尤其是在您遍历结果并连接到其他表时。延迟加载可能是真正的性能杀手。

于 2012-08-31T14:53:38.203 回答