Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架查询速度非常慢_C#_Sql_Entity Framework - Fatal编程技术网

C# 实体框架查询速度非常慢

C# 实体框架查询速度非常慢,c#,sql,entity-framework,C#,Sql,Entity Framework,我正在从日志表中读取记录。该表目前有260000条记录,共有8列。这是通过EF6生成的代码 using (var ctx = new DbEntities()) { ctx.Configuration.ProxyCreationEnabled = false; ctx.Configuration.AutoDetectChangesEnabled = false; ctx.Configuration.LazyLoadingEnabled = false; Stopw

我正在从日志表中读取记录。该表目前有260000条记录,共有8列。这是通过EF6生成的代码

using (var ctx = new DbEntities())
{
    ctx.Configuration.ProxyCreationEnabled = false;
    ctx.Configuration.AutoDetectChangesEnabled = false;
    ctx.Configuration.LazyLoadingEnabled = false;
    Stopwatch sw = Stopwatch.StartNew();
    var k = ctx.Logs.Where(l => l.ApplicationId == id && l.Level <= 3 && (l.Dat == 20160514 ||l.Dat == 20160513 ) ).ToList();
    sw.Stop();
}
使用(var ctx=new DbEntities())
{
ctx.Configuration.ProxyCreationEnabled=false;
ctx.Configuration.AutoDetectChangesEnabled=false;
ctx.Configuration.LazyLoadingEnabled=false;
秒表sw=Stopwatch.StartNew();

var k=ctx.Logs.Where(l=>l.ApplicationId==id&&l.LevelEF必须将SQL的结果映射到一个对象中,这可能涉及反射和映射器的动态加载,以将SQL结果转换为一个
日志列表。
。如果对单个结果计时,请尝试在同一上下文中多次执行相同的操作。您会发现,映射器esult执行时间将减少。这是因为映射程序已加载,不需要检索


我不是EF方面的专家,我只是对同样的问题进行了试验,发现几秒钟的延迟只是针对上下文的第一次执行的问题。

经过一些尝试和错误后,我发现我可以将所需时间至少缩短一半

通过首先进行Count()调用,我可以将请求分成多个部分,并以小的增量逐页请求

因此,同样的2213个项目现在需要3-4秒,每个项目只需要1000个并行调用。10000个项目过去需要60秒,而这种方法只需要18秒

async Task<List<Log>> GeLogs(int count, int pageSize, string search)
{
    var pages = Math.Ceiling(count / s);

    var tasks = new Task<List<Log>>[(int)pages];
    for (int i = 0; i < pages; i++)
    {
        var page = i;
        tasks[i] = Task.Run(() =>
        {
            using (var c = new DbEntities())
            {
                c.Configuration.ProxyCreationEnabled = false;
                c.Configuration.AutoDetectChangesEnabled = false;

                var query = c.Logs.SqlQuery("SELECT * FROM Log WITH(NOLOCK) " + search + string.Format("ORDER BY LogTime DESC OFFSET (({0} - 1) * {1}) ROWS FETCH NEXT {1} ROWS ONLY", page + 1, (int)s));

                return query.ToList();
            }
        });
    }
}
异步任务GeLogs(int计数、int页面大小、字符串搜索) { 变量页=数学上限(计数/秒); var tasks=新任务[(int)页]; 对于(int i=0;i { 使用(var c=new DbEntities()) { c、 Configuration.ProxyCreationEnabled=false; c、 Configuration.AutoDetectChangesEnabled=false; var query=c.Logs.SqlQuery(“使用(NOLOCK)从日志中选择*”+search+string.Format(“按日志时间顺序描述偏移量({0}-1)*{1})行仅获取下一个{1}行”,第+1页,(int)s)); 返回query.ToList(); } }); } }

小于1000似乎不会产生更好的结果。

在sql management studio上执行相同的查询

执行后,单击“显示执行计划”按钮

阅读报告中的问题。
如果需要,执行添加缺少索引的修复程序。

我怀疑查询本身会花费那么长的时间。可能是ToList的枚举花费了最多的时间。是否应根据相关设计的性质将
LazyLoadingEnabled
设置为
true
course@TiesonT.“我怎么能测试它呢?”米基德说,那是一个绝望的决定机会,不管是哪种方式,似乎都不会产生什么影响difference@jdweng什么XML?EF默认情况下不使用XML,他还没有开始通过WCF将结果返回给客户端。我觉得这很有可能。EF应该在与SSMS相当的时间内运行,一旦它“预热”,上次我批量这么做时,EF很高兴地映射了50万个对象半秒钟内就可以查字典了。想解释一下这是怎么回事吗?这么慢?-1,是时候了解EF的工作原理了。@TomTom我想你的测试是在不同的环境下进行的,在不同的环境下,有不同的设置,可能有不同的EF版本。事实上,你对EF的体验是不同的这不会使我的经验无效,也不会使我针对同一上下文测试多个查询的建议出错。与其尝试缩减我的答案,不如发布你自己的答案,并向我们其他人解释EF的工作原理。不是真的。除非你使用的是完全过时的EF版本(OP没有说他使用了,而且会很旧)还有一部手机作为数据库服务器,可能通过一个10兆的网络连接它,这是相关的。因为这是唯一的方法,我不能认为答案非常糟糕。你想了解你使用的工具吗?EF是开源的。@TomTom所以你的答案是“阅读代码”?似乎效率不高。很抱歉,我给OP的建议轻视了你。我看了这一点,还打开了统计数据,我发现在最糟糕的时候,我的查询只需不到半秒钟。我认为问题在于EF,我只是不知道该怎么办。
SELECT 
    [Extent1].[LogId] AS [LogId], 
    [Extent1].[ApplicationId] AS [ApplicationId], 
    [Extent1].[Type] AS [Type], 
    [Extent1].[Source] AS [Source], 
    [Extent1].[Message] AS [Message], 
    [Extent1].[LogTime] AS [LogTime], 
    [Extent1].[Level] AS [Level], 
    [Extent1].[Dat] AS [Dat]
    FROM [dbo].[Log] AS [Extent1]
    WHERE ([Extent1].[ApplicationId] = @p__linq__0) AND ([Extent1].[Level] <= 3) AND ([Extent1].[Dat] IN (20160514,20160513))
-- p__linq__0: '2648' (Type = Int32, IsNullable = false)
-- Executing at 5/14/2016 8:38:38 PM -04:00
-- Completed in 101 ms with result: SqlDataReader
async Task<List<Log>> GeLogs(int count, int pageSize, string search)
{
    var pages = Math.Ceiling(count / s);

    var tasks = new Task<List<Log>>[(int)pages];
    for (int i = 0; i < pages; i++)
    {
        var page = i;
        tasks[i] = Task.Run(() =>
        {
            using (var c = new DbEntities())
            {
                c.Configuration.ProxyCreationEnabled = false;
                c.Configuration.AutoDetectChangesEnabled = false;

                var query = c.Logs.SqlQuery("SELECT * FROM Log WITH(NOLOCK) " + search + string.Format("ORDER BY LogTime DESC OFFSET (({0} - 1) * {1}) ROWS FETCH NEXT {1} ROWS ONLY", page + 1, (int)s));

                return query.ToList();
            }
        });
    }
}