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对实体对象的变动进行跟踪,实现跟踪的方式有两种:变动跟踪快照和变动跟踪代理. 变动跟踪快照:前面 ...
随机推荐
- gdb调试4--回退
加入你正在使用GDB7.0以上版本的调试器并且运行在支持反向调试的平台,你就可以用以下几条命令来调试程序: reverse-continue 反向运行程序知道遇到一个能使程序中断的事件(比如断点,观察 ...
- 【题解】Tree-String Problem Codeforces 291E AC自动机
Prelude 传送到Codeforces:(/ω\)--- (/ω•\) Solution 很水的一道题. 对查询的串建出来AC自动机,然后树上随便跑跑就行了. 为什么要写这篇题解呢? 我第一眼看到 ...
- P1486 [NOI2004]郁闷的出纳员
P1486 [NOI2004]郁闷的出纳员 题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷 ...
- Hadoop基础-HDFS的API实现增删改查
Hadoop基础-HDFS的API实现增删改查 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客开发IDE使用的是Idea,如果没有安装Idea软件的可以去下载安装,如何安装 ...
- java基础-引用数据类型之二维数组(Array)
java基础-引用数据类型之二维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前我们学习过了Java的一维数组,所谓的二维数组就是元素是一堆一维数组的数组,换 ...
- openstack组件的数据库操作
一.基础 SQLAlchemy http://docs.sqlalchemy.org/en/rel_0_9/index.html 对数据库进行操作的工具:xxx-manage db ... 二.数据库 ...
- 转:IOS里的动画
摘要 本文主要介绍核iOS中的动画:核心动画Core Animation, UIView动画, Block动画, UIImageView的帧动画. 核心动画Core Animation UIView动 ...
- snprintf()解析
snprintf(ssid_mac,sizeof(ssid_mac),"%s_%02X%02X",ssid,macval[4],macval[5]); ssid_mac = ssi ...
- Spark记录-Scala介绍
Scala是可扩展语言的缩写,是一种混合功能编程语言. 它由Martin Odersky创建. Scala顺利整合面向对象和函数式语言的功能. Scala被编译后在Java虚拟机上运行. 许多现有公司 ...
- c# lock的误解
一直以为lock 一个实例就可以了,没想到实例的类型还是有区别的 static object lockObjStatic = new object(); object lockObj = new ob ...