c# - 从大型数据库中检索行时优化灵活的 Linq to Entity 标准的性能

标签 c# sql-server entity-framework linq-to-entities

我的数据库包含数十亿行。 我创建了从用户参数中接收参数并通过这些参数切割数据库的函数。 这适用于小型数据库(30000 行),但是当我尝试在大型数据库上使用此函数时,我从 SQLSERVER 得到了 TIMEOUTEXCEPTION

这是我的代码:

public static IQueryable<LogViewer.EF.InternetEF.Log> ExecuteInternetGetLogsQuery(FilterCriteria p_Criteria, ref GridView p_Datagrid)
{
    IQueryable<LogViewer.EF.InternetEF.Log> internetQuery = null;

    using (InternetDBConnectionString context = new InternetDBConnectionString())
    {
        internetQuery = context.Logs;
        if ((p_Criteria.DateTo != null && p_Criteria.DateFrom != null))
        {
            internetQuery = internetQuery.Where(c => c.Timestamp >= p_Criteria.DateFrom && c.Timestamp < p_Criteria.DateTo);
        }
        else if (p_Criteria.DateFrom != null && p_Criteria.DateFrom > DateTime.MinValue)
        {
            internetQuery = internetQuery.Where(c => c.Timestamp >= p_Criteria.DateFrom);
        }
        else if (p_Criteria.DateTo != null && p_Criteria.DateTo > DateTime.MinValue)
        {
            internetQuery = internetQuery.Where(c => c.Timestamp < p_Criteria.DateTo);
        }
        if (!string.IsNullOrEmpty(p_Criteria.FreeText))
        {
            internetQuery = internetQuery.Where(c => c.FormattedMessage.Contains(p_Criteria.FreeText));
        }

        if (p_Criteria.Titles.Count > 0)
        {
            internetQuery = internetQuery.AsEnumerable().Where(c => p_Criteria.Titles.Contains(c.Title)).AsQueryable();
        }
        if (p_Criteria.MachineNames.Count > 0)
        {
            internetQuery = internetQuery.AsEnumerable().Where(c => p_Criteria.MachineNames.Contains(c.MachineName)).AsQueryable();
        }
        if (p_Criteria.Severities.Count > 0)
        {
            internetQuery = internetQuery.AsEnumerable().Where(c => p_Criteria.Severities.Contains(c.Severity)).AsQueryable();
        }
        internetQuery= internetQuery.OrderByDescending(c=>c.LogID);
        if (internetQuery.Count() > p_Criteria.TopValue)
        {
            internetQuery = internetQuery.Take(p_Criteria.TopValue);
        }
        p_Datagrid.DataSource = internetQuery;
        p_Datagrid.DataBind();
        return internetQuery;

    }  
}

我的 SQL 版本是 2005。 我在 p_Datagrid.DataBind(); 行上遇到异常。

有什么建议吗? 谢谢

最佳答案

我可以看到您有以下选项:

  • 增加超时时间(Bad idé 只是将问题转移到 future )
  • 而不是执行 linq 查询。通过存储过程获取数据
  • 制作网格页面。因此,您只需检索目标页面的数据。
  • 查看查询计划,看看您是否可以在您正在执行 where 语句和 order by 的列上建立任何索引。
  • 为什么您需要在数据网格中包含数十亿行。有什么要求?也许您可以只显示 top 1000top 10000。因为从用户的角度来看,我看不出有十亿行的网格有任何好处。

那只是我的想法。

编辑

如果我有这个功能,我会开始查看这部分代码:

if (p_Criteria.Titles.Count > 0)
{
     internetQuery = internetQuery.AsEnumerable().Where(c => p_Criteria.Titles.Contains(c.Title)).AsQueryable();
}
if (p_Criteria.MachineNames.Count > 0)
{
      internetQuery = internetQuery.AsEnumerable().Where(c => p_Criteria.MachineNames.Contains(c.MachineName)).AsQueryable();
}
if (p_Criteria.Severities.Count > 0)
{
      internetQuery = internetQuery.AsEnumerable().Where(c => p_Criteria.Severities.Contains(c.Severity)).AsQueryable();
}

这实际上使结果成为一个 IEnumerable,然后您在内存中执行 where 语句并调用数据库。执行此操作也可能会遇到问题,因为当您调用相关表时,它会调用数据库。也许您可以获取行,然后使用 IQueryable 的 id 执行 contains 。执行此操作时使用 IQueryable 尿布的所有优点。

关于c# - 从大型数据库中检索行时优化灵活的 Linq to Entity 标准的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10190881/

相关文章:

asp.net - Entity Framework 6 - 使用 select 的嵌套查询中的空值

C# 发送 POST 到 PHP MYSQL 但没有收到任何内容

SQL服务器查询: how to select customers with more than 1 order

SQL-使用条件选择每组前 3 个值

entity-framework - 如何使用 Entity Framework 代码优先在虚拟列上添加索引?

entity-framework - 在 Entity Framework 中使用 EntityDataSource 与 ObjectDataSource 的优缺点?

c# - 使用 C# 将 word 文档转换为文本文档

c# - 获取 Xml 属性

c# - 当内部调用不是自然异步时,如何创建自然异步方法?

sql-server - 如何将空日期变量传递到 SQL Server 数据库