【MVC+MySQL+EntityFramework】查询性能优化笔记
通过在DbContext中定了表之间的关系,查询后在View中通过item.ProjectOverHour来显示关联表数据。
modelBuilder.Entity<ProjectOverHour>()
.HasMany(e => e.DailyReports)
.WithRequired(e => e.ProjectOverHour)
.HasForeignKey(e => new { e.ProjectIndex, e.EmployeeId, e.ReportDate })
.WillCascadeOnDelete(false);
开发完后发现页面仅仅显示10条记录耗时已经超过1s了。
调查后发现如下原因:
1、EntityFramework中,关联表数据不是在查询时加载的,而是在用到时(即View中调用item.ProjectOverHour时)才会去DB查询。
将画面显示条数改为20条后,页面加载时间成正比例上升。
考虑不让EntityFramework执行多次查询,使用Select方法使其一次查询出所需要的关联数据。
Select<DailyReport, DailyReportSearchResultViewModel>(d => new DailyReportSearchResultViewModel()
{
...
OverHour = d.ProjectOverHour.OverHour,
...
});
这样修改后生成的SQL中关联了需要的表,并且只执行了一次查询。
因为在DbContext中定义的是外键关系,导致生成的SQL文是InnerJoin的关系,而不是想定的LeftJoin关系。
调查后没有发现如何在DbContext中定义Left Join关系。(有WithOptional方法,但执行时总是出错)
后来改用如下写法,实现了Left Join的效果,查询结果也是正确的。
from d in dailyReportsQuery
join ot1 in db.ProjectOverHours
on new { ProjectIndex = d.ProjectIndex, EmployeeId = d.EmployeeId, ReportDate = d.ReportDate }
equals new { ProjectIndex = ot1.ProjectIndex, EmployeeId = ot1.EmployeeId, ReportDate = ot1.WorkDate } into ottemp
from ot in ottemp.DefaultIfEmpty()
select new DailyReportSearchResultViewModel
{
...
ApprovalOverHour = ot.ApprovalOverHour,
...
};
但是页面加载时间仍然很长(4s左右)。
后来发现把关联表中的两个View的算法改为Template后,数据查询快了很多。
这个感觉很没道理,查询应该Meger查询更快才对。
在用生成的SQL测试时,发现创建索引占据了99%的时间。
原来关联View的业务主键,在原来的表里并不是主键。
将原来的表里追加相应的索引后,查询快了很多。
逐个把关联的表都加了索引。
上述修改后,数据少时页面加载页很快(0.1s左右)。
但是在追加了2w条数据后再测试时,发现页面加载又变慢了。
还是EntityFramework生成的SQL文的问题。
因为使用OrderBy来排序,并且使用了分页,生成的SQL文变成了如下的形式。
SELECT
...
FROM (SELECT
...
FROM `dailyreport` AS `Extent1`
LEFT OUTER JOIN ...
INNER JOIN ...
WHERE (0 = `Extent1`.`DeleteFlag`) ... ) AS `Project1`
ORDER BY
`Project1`.`...` DESC,
`Project1`.`...` ASC,
`Project1`.`...` DESC
LIMIT 0,10
把查询结果作为子查询,然后再排序和分页。
查询用时1.1s,其中Sending data占了99%的时间。
仍然比最初的页面加载时间要多。
最后改为将InnerJoin的表用Select方法取出相关数据,LeftJoin的表的数据,通过循环Select结果集,单独取得这些数据。
修改后开发环境页面加载时间在0.2~0.3s,服务器环境在0.4~0.5s。
虽然不是很理想,但是对于社内用的小系统来说,性能已经可以接受了。
2、MySql的DB服务器是放在一台虚拟机上的,性能一直不好,并且已经有别的系统在用。
因为要用到该DB服务器上的另一个数据库的数据,所以考虑把本系统的数据建立在一台新机器上,然后建立远程连接表来取数据。
但发现每次查询都要从远程服务器取得所有的数据然后再查询,效率极差。
最后还是只好放在该服务器上了。
CREATE TABLE IF NOT EXISTS `tablename`` (
......
) ENGINE=FEDERATED DEFAULT CHARSET=utf8
CONNECTION='mysql://user:password@server:3306/schema/tablename';
如果DB能换台性能好些的服务器,应该能带来不少的提升。
【MVC+MySQL+EntityFramework】查询性能优化笔记的更多相关文章
- MySql学习—— 查询性能优化 深入理解MySql如何执行查询
本篇深入了解查询优化和服务器的内部机制,了解MySql如何执行特定查询,从中也可以知道如何更改查询执行计划,当我们深入理解MySql如何真正地执行查询,明白高效和低效的真正含义,在实际应用中就能扬长避 ...
- MySQL之查询性能优化(四)
优化特定类型的查询 COUNT()的作用 COUNT()是一个特殊函数,有两个非常不同的作用:它可以统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL). 如果在COUN ...
- MySQL之查询性能优化(三)
MySQL查询优化器的局限性 MySQL的万能“嵌套循环”并不是对每种查询都是最优的.不过还好,MySQL查询优化只对少部分查询不适用,而且我们往往可以通过改写查询让MySQL高效地完成工作. 关联子 ...
- MySQL之查询性能优化(二)
查询执行的基础 当希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的.MySQL执行一个查询的过程,根据图1-1,我们可以看到当向MySQL发送一个请求时, ...
- MySQL之查询性能优化(一)
为什么查询速度会慢 通常来说,查询的生命周期大致可以按照顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端.其中“执行”可以认为是整个生命周期中最重要的阶段, ...
- MySQL分页查询性能优化
当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的一些方 ...
- sql 2008 查询性能优化笔记
索引: set statistics io on select p.productID,p.name,p.Weight,p.StandardCost from production.product p ...
- mysql笔记03 查询性能优化
查询性能优化 1. 为什么查询速度会慢? 1). 如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减 ...
- 到底该不该使用存储过程 MySQL查询性能优化一则
到底该不该使用存储过程 看到<阿里巴巴java编码规范>有这样一条 关于这条规范,我说说我个人的看法 用不用存储过程要视所使用的数据库和业务场景而定的,不能因为阿里巴巴的技术牛逼,就视 ...
随机推荐
- 总结分析Java常见的四种引用
从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 1.强引用 本章前文介绍的引用实际上都是强引用, ...
- EXISTS运算符
和IN.ANY.ALL等运算符不同,EXISTS运算符是单目运算符,它不与列匹配,因此它也不要求待匹配的集合是单列的.EXISTS运算符用来检查每一行是否匹配子查询,可以认为EXISTS就是用来测试子 ...
- eclipse git解决冲突
转自 http://blog.csdn.net/rosten/article/details/17068285 1.工程->Team->同步: 2.从远程pull至本地,就会出现如下内容 ...
- Topcoder Srm 671 Div2 1000 BearDestroysDiv2
\(>Topcoder \space Srm \space 671 \space Div2 \space 1000 \space BearDestroysDiv2<\) 题目大意 : 有一 ...
- BZOJ 1475 方格取数(二分图最大点权独立集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1475 [题目大意] 给出一个n*n的方格,从中取一些不相邻的数字,使得和最大 [题解] ...
- 解决 javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
解决这个异常的重点就在于下载两个jar包: bcprov-ext-jdk15on-1.52 bcprov-jdk15on-1.52 传送门:https://stackoverflow.com/ques ...
- Android:导入工程
File->new->Project->android->Android Project from Existing code 在Root Directory:中填写Andro ...
- HDU 4305 Lightning(计算几何,判断点在线段上,生成树计数)
Lightning Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- 详解MySQL性能优化(二)
http://www.jb51.net/article/70530.htm 七.MySQL数据库Schema设计的性能优化高效的模型设计 适度冗余-让Query尽两减少Join 大字段垂直分拆-sum ...
- mac 安装 composer
使用 curl 指令下载: curl -sS https://getcomposer.org/installer | php 或是沒有安裝 curl ,也可以用 php 指令下载: php -r &q ...