最近一个项目,使用微软的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

SQL Server Profiler的使用的更多相关文章

  1. SQL Server Profiler

    一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问 ...

  2. SQL Server Profiler使用教程,通俗易懂才是王道

    做开发,平时难免和数据库打交道,特别是写存储过程,对于我们这些不常写SQL的人来说是一件极其痛苦的事,每次写完运行总是有错,如果用的是本地数据库的话还好,可以在本机调试SQL,那如果在数据库在服务器上 ...

  3. SQL Server Profiler教程

    SQL Server Profiler是SQL Server企业版自带的一个sql 语句跟踪和分析工具,功能十分强大.熟练地使用它,对我们分析数据库性能问题很有帮助,比如当数据访问使用EF等ORM框架 ...

  4. SQL Server Profiler工具

    一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问 ...

  5. SQL2005 : 如何在SQL Server Profiler (事件查看器)中 跟踪查看死锁恢复

    SQL Profiler 通过 SQL Profiler 工具程序,可监控应用程序如何访问数据库引擎.普通来说,当系统性能需要优化或是应用程序对数据库访问的结果不合预期,都可以使用该工具确认视图问题所 ...

  6. SQL Server Profiler使用方法

    一.SQL Server Profiler使用方法 1.单击开始--程序--Microsoft SQL Server 2005--性能工具--SQL Server Profiler,如下图:   2. ...

  7. 降龙十八掌之一:(亢龙有悔)SQL Server Profiler和数据库引擎优化顾问

    简介 说到Sql的[性能工具]真是强大,SQL Server Profiler的中文意思是SQL Server事件探查,这个到底是做什么用的呢?我们都知道探查的意思大多是和监视有关,其实这个SQL S ...

  8. SQL Server Profiler:使用方法和指标说明

    SQL Server Profiler的中文意思是SQL Server事件探查,一个Sql的监视工具,可以具体到每一行Sql语句,每一次操作,和每一次的连接.感觉这个工具的作用还是很大的,给大家分享一 ...

  9. 解决 SQL Server Profiler 跟踪[不断]出现检索数据

    问题简单回顾: 当我们使用SQL Server Profiler根据数据时,有时刚打开什么也没干呢,就显示很多数据了,当我们用橡皮擦清除,没过两秒就又有了,如图: 是不是很恼火!~不怕,解决方案如下: ...

  10. 运行sql server profiler所需的权限

    ********运行Sql Server Profiler所需的权限(performance)*********/ --EG. -- 使用TRACE帐户(Performancetest)跟踪Sql S ...

随机推荐

  1. 《Web前端开发修炼之道》-读书笔记CSS部分

    如何组织CSS-分层 应用 css 的能力分两部分:一部分是css的API,重点是如何用css控制页面内元素的样式:另一部分是css框架,重点是如何对 css 进行组织.如何组织 css 可以有多种角 ...

  2. AngularJS学习篇(二)

    AngularJS 指令 AngularJS 通过被称为 指令 的新属性来扩展 HTML. AngularJS 通过内置的指令来为应用添加功能. AngularJS 允许你自定义指令. Angular ...

  3. AngularJS学习篇(一)

    AngularJS 使用 表达式 把数据绑定到 HTML. AngularJS 表达式 AngularJS 表达式写在双大括号内:{{ expression }}. AngularJS 表达式把数据绑 ...

  4. [译]ASP.NET Core 2.0 系列文章目录

    基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...

  5. mysql +keeplive+drbd高可用架构

    1MySQL+DRBD+keepalived高可用架构 DRBD(DistributedReplicatedBlockDevice)是一个基于块设备级别在远程服务器直接同步和镜像数据的开源软件,类似于 ...

  6. hadoop的webUI查看Live Nodes为1

    开起了两个节点,而且jps查看确实开启了,但是用web端50070查看却一直显示为1 经过排查,将虚拟机直接copy一份,但是之前配置好hadoop环境的namenode格式化(format)生成的文 ...

  7. Node.js初探之POST方式传输

    小知识:POST比GET传输的数据量大很多 POST发数据--"分段" 实例: 准备一个form.html文件: <!DOCTYPE html> <html> ...

  8. 我是如何理解Android的Handler模型_3

    AsyncTask则相当于现代化的电话系统,接线员的功能被完全封装了. 对于上例,新建更新TextView的类并继承AsyncTack类,如下: class UpdataTV extends Asyn ...

  9. C# 链接MySql数据库

    C# 链接MySql数据库只得注意的几点: 1.C#链接MySql数据库要在网上下载一个mysql-connector-net-6.0.4-noinstall.rar  这里面放的都是一堆dll .将 ...

  10. [转载] KAFKA分布式消息系统

    转载自http://blog.chinaunix.net/uid-20196318-id-2420884.html Kafka[1]是linkedin用于日志处理的分布式消息队列,linkedin的日 ...