Entity Framework Code First 在Object Join Linq查询时出现全表查询的语句。
最近一个项目,使用微软的Entity Framework的ORM框架的项目,部署到现场后,出现了系统缓慢,多个客户端的内存溢出崩溃的问题。
打开了SQL Server Profiler(SQL Server Profiler的简单使用)排查,发现有全表查询的语句,这表中有上万条数据,所以客户端查询后内存溢出了。
从代码中排查是否有直接全表查询的语句,结果未找到,后来在网上搜索到Linq to Object 连接(join) Linq to Entity时可能会引起全表查询。(https://www.cnblogs.com/gxlinhai/p/4263393.html)
所以这里也创建了一个demo做了进一步的了解。
此Demo 使用Entity Framework的ORM框架,只需要配置数据库连接,能自动生成数据库,并创建一些数据。
表有Entity和Foo两个表,其中Foo表中有Entity表的外键。
打开SQL Server Profiler检测生成的语句。
测试一,用IEnumerable来连表查询。
IEnumerable<Foo> foos = db.Foos;
var objectNames = (from foo in foos
join en in db.Entitys
on foo.EntityId equals en.EntityId
select foo.Name).ToList();
之后在SQL Server Profiler中监测到如下语句:
SELECT
[Extent1].[EntityId] AS [EntityId],
[Extent1].[Name] AS [Name],
[Extent1].[Notes] AS [Notes]
FROM [dbo].[Entities] AS [Extent1]
出现了Entity表全表查询的语句。
测试二, 用var来连表查询。
var foos = db.Foos;
var objectNames = (from foo in foos
join en in db.Entitys
on foo.EntityId equals en.EntityId
select foo.Name).ToList();
在SQL Server Profiler中,监测到的语句如下
SELECT
[Extent1].[Name] AS [Name]
FROM [dbo].[Foos] AS [Extent1]
INNER JOIN [dbo].[Entities] AS [Extent2] ON [Extent1].[EntityId] = [Extent2].[EntityId]
没有出现全表查询的语句。
测试三,用IQueryable来连表查询
IQueryable<Foo> foos = db.Foos;
var objectNames = (from foo in foos
join en in db.Entitys
on foo.EntityId equals en.EntityId
select foo.Name).ToList();
在SQL Server Profiler中,监测到的语句如下
SELECT
[Extent1].[Name] AS [Name]
FROM [dbo].[Foos] AS [Extent1]
INNER JOIN [dbo].[Entities] AS [Extent2] ON [Extent1].[EntityId] = [Extent2].[EntityId]
没有出现全表查询的语句。
测试四:结合别人说的代码,修改如下
List<MyObject> objectList = new List<MyObject>();
objectList.Add(new MyObject { Identity = 1, Name = "Jack", Age = 30 });
objectList.Add(new MyObject { Identity = 2, Name = "Sam", Age = 28 });
objectList.Add(new MyObject { Identity = 3, Name = "Lucy", Age = 23 }); var objectNames = (from foo in objectList
join en in db.Entitys
on foo.Identity equals en.EntityId
select foo.Name).ToList();
在SQL Server Profiler中,监测到的语句如下
SELECT
[Extent1].[EntityId] AS [EntityId],
[Extent1].[Name] AS [Name],
[Extent1].[Notes] AS [Notes]
FROM [dbo].[Entities] AS [Extent1]
又出现了Entity全表查询的语句。
结论:
测试1:返回结果为IEnumerable时,有可能数据已经缓存到内存里了,作为了object,这样再linq查询时,不会重新调整sql语句,导致了连接表全表查询后在内存中过滤。
测试2、3: IQueryable在连表查询时,最后会重新生成sql语句来查询。var默认为DbSet,DbSet也会重新生成sql语句来查询。
测试4: 直接证明了object与linq查询,导致查询语句会变成全表查询。
Demo见如下:
百度网盘:https://pan.baidu.com/s/1cDEIS2
提取密码:qwnb
Entity Framework Code First 在Object Join Linq查询时出现全表查询的语句。的更多相关文章
- Entity Framework Code First 映射继承关系
转载 http://www.th7.cn/Program/net/201301/122153.shtml Code First如何处理类之间的继承关系.Entity Framework Code Fi ...
- 使用 Entity Framework Code First
使用 Entity Framework Code First 在家闲着也是闲着,继续写我的[ASP.NET MVC 小牛之路]系列吧.在该系列的上一篇博文中,在显示书本信息列表的时候,我们是在程序代码 ...
- Entity Framework Code First - Change Tracking
In this post we will be discussing about change tracking feature of Entity Framework Code First. Cha ...
- Entity Framework Code First数据库连接
1. 安装Entity Framework 使用NuGet安装Entity Framework程序包:工具->库程序包管理器->程序包管理器控制台,执行以下语句: PM> Insta ...
- Entity Framework Code First属性映射约定
Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...
- Entity Framework Code First关系映射约定
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- Entity Framework Code First执行SQL语句、视图及存储过程
1.Entity Framework Code First查询视图 Entity Framework Code First目前还没有特别针对View操作的方法,但对于可更新的视图,可以采用与Table ...
- Entity Framework Code First使用DbContext查询
DbContext.DbSet及DbQuery是Entity Framework Code First引入的3个新的类,其中DbContext用于保持数据库会话连接,实体变化跟踪及保存,DbSet用于 ...
- Entity Framework Code First实体对象变动跟踪
Entity Framework Code First通过DbContext.ChangeTracker对实体对象的变动进行跟踪,实现跟踪的方式有两种:变动跟踪快照和变动跟踪代理. 变动跟踪快照:前面 ...
随机推荐
- Dockerfile编写注意事项
转载自:https://blog.fundebug.com/2017/05/15/write-excellent-dockerfile/ 一.目标 更快的构建速度 更小的Docker镜像大小 更少的D ...
- java synchronized 的原理。
synchronized的作用大概分为三种: 1.确保多线程互斥的访问多线程代码.2.保证变量的可见性.3.防止指令重排序. 那么synchronized 是如何实现这些功能的. public cla ...
- UITableViewCell的separatorInset属性
separatorInset这个属性是IOS7后才有的属性,所以需要判断一下,才能修改 if (IOS7_OR_LATER) { cell.separatorInset = UIEdgeInsetsZ ...
- bzoj千题计划156:bzoj1571: [Usaco2009 Open]滑雪课Ski
http://www.lydsy.com/JudgeOnline/problem.php?id=1571 DP不一定全部全状态转移 贪心的舍去一些不合法的反而更容易转移 在一定能力范围内,肯定滑雪所需 ...
- bzoj千题计划152:bzoj3405: [Usaco2009 Open]Grazing2 移动牛棚
http://www.lydsy.com/JudgeOnline/problem.php?id=3405 n个牛棚,n-1段 因为要求距离尽量大,而且尽可能多的为d 所以: 第1个牛棚一定在位置1 最 ...
- dubbo Filter
官方说明: 调用拦截扩展 扩展说明 服务提供方和服务消费方调用过程拦截,Dubbo 本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截都会被执行,请注意对性能的影响. 约定: 用户自定义 fi ...
- 深入浅出JavaScript之跨域总结
什么是跨域 1.document.domain+iframe的设置 2.动态创建script 3.利用iframe和location.hash 4.window.name实现的跨域数据传输 5.使用H ...
- mysql修改表操作
一: 修改表信息 1.修改表名 alter table test_a rename to sys_app; 2.修改表注释 alter table sys_application comment '系 ...
- 29、HashSet简介
Set的特点 Set里面存储的元素不能重复,没有索引,存取顺序不一致. package com.monkey1024.set; import java.util.HashSet; /** * Set的 ...
- 【navicat112_premium】navicat112_premium数据库连接工具安装过程
此工具及其方便,可以连接mysql.oracle.sqlserver登数据库... 1.下载安装包Navicat Premium_11.2.7简体中文版.rar 下载地址:http://qiaoliq ...