通过在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能换台性能好些的服务器,应该能带来不少的提升。

已添加到【MVC5】ASP.NET MVC 项目笔记汇总

【MVC+MySQL+EntityFramework】查询性能优化笔记的更多相关文章

  1. MySql学习—— 查询性能优化 深入理解MySql如何执行查询

    本篇深入了解查询优化和服务器的内部机制,了解MySql如何执行特定查询,从中也可以知道如何更改查询执行计划,当我们深入理解MySql如何真正地执行查询,明白高效和低效的真正含义,在实际应用中就能扬长避 ...

  2. MySQL之查询性能优化(四)

    优化特定类型的查询 COUNT()的作用 COUNT()是一个特殊函数,有两个非常不同的作用:它可以统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL). 如果在COUN ...

  3. MySQL之查询性能优化(三)

    MySQL查询优化器的局限性 MySQL的万能“嵌套循环”并不是对每种查询都是最优的.不过还好,MySQL查询优化只对少部分查询不适用,而且我们往往可以通过改写查询让MySQL高效地完成工作. 关联子 ...

  4. MySQL之查询性能优化(二)

    查询执行的基础 当希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的.MySQL执行一个查询的过程,根据图1-1,我们可以看到当向MySQL发送一个请求时, ...

  5. MySQL之查询性能优化(一)

    为什么查询速度会慢 通常来说,查询的生命周期大致可以按照顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端.其中“执行”可以认为是整个生命周期中最重要的阶段, ...

  6. MySQL分页查询性能优化

    当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的一些方 ...

  7. sql 2008 查询性能优化笔记

    索引: set statistics io on select p.productID,p.name,p.Weight,p.StandardCost from production.product p ...

  8. mysql笔记03 查询性能优化

    查询性能优化 1. 为什么查询速度会慢? 1). 如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减 ...

  9. 到底该不该使用存储过程 MySQL查询性能优化一则

    到底该不该使用存储过程   看到<阿里巴巴java编码规范>有这样一条 关于这条规范,我说说我个人的看法 用不用存储过程要视所使用的数据库和业务场景而定的,不能因为阿里巴巴的技术牛逼,就视 ...

随机推荐

  1. lamp字符编码的转换规则

    1.lamp字符编码的转换规则 lamp(Linux+Apache+Mysql+PHP) 1.1GB 2312 GB 2312 或 GB 2312-80 是中国国家标准简体中文字符集,全称<信息 ...

  2. HDU 6280 From Tree to Graph(2018 湘潭邀请 E题,树的返祖边)

    其实打返祖边就相当于$x$到祖先这一段点(不包括两端)答案都要减$1$. 然后每个点最多减$1$次$1$. #include <bits/stdc++.h> using namespace ...

  3. 基于SAAJ的客户端

    概述 SAAJ - SOAP with Attachments API for JAVA 结构图如下: 正文 1. 如何获取soap请求的关键参数 关键的参数有四个: xmlns - xml命名空间如 ...

  4. 【解决问题】centOS 7 设置固定IP,无法上外网

    使用Xenserver搭建服务器集群,在安装centOS时候,发现如果将服务器IP设置成为static ip,只能内网互通,无法上外网(ping www.baidu.com 失败) 网上搜索了一下,发 ...

  5. [BZOJ4246]两个人的星座(计算几何)

    4246: 两个人的星座 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 101  Solved: 55[Submit][Status][Discuss ...

  6. JZYZOJ1383 [usaco2003feb]impster 位运算 最短路

    http://172.20.6.3/Problem_Show.asp?id=1383  找能到达某个状态的最小操作数,然后把所有状态扫一遍即可,要额外判定一下起始就有的状态(如果起始里没有0那么这些状 ...

  7. HDU 6057 Kanade's convolution(FWT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6057 [题目大意] 有 C[k]=∑_(i&j=k)A[i^j]*B[i|j] 求 Ans ...

  8. BZOJ 1430 小猴打架(prufer编码)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1430 [题目大意] 一开始森林里面有N只互不相识的小猴子,它们经常打架, 但打架的双方 ...

  9. 【数论】【莫比乌斯反演】【线性筛】bzoj2005 [Noi2010]能量采集

    http://blog.csdn.net/Clove_unique/article/details/51089272 Key:1.连接平面上某个整点(a,b)到原点的线段上有gcd(a,b)个整点. ...

  10. 【DFS】【拓扑排序】【动态规划】Gym - 100642A - Babs' Box Boutique

    给你10个箱子,有长宽高,每个箱子你可以决定哪个面朝上摆.把它们摞在一起,边必须平行,上面的不能突出来,问你最多摆几个箱子. 3^10枚举箱子用哪个面.然后按长为第一关键字,宽为第二关键字,从大到小排 ...