zoukankan      html  css  js  c++  java
  • 实体框架 (EF) 入门 => 六、性能注意事项

    这个还真是复杂,看了看微软的文档,有些根本就看不懂,有些能看懂,但对我这种菜鸟也不会去用。

    无从下手啊,前面放了几个链接,挨个试试吧。

    一、显式打开连接

    这个我测试过,有些时候,需要我们显示打开连接,有时不用。

    1、.SaveChanges()

    没写错吧,嘿嘿。

    这个不需要关注连接的问题,因为不管之前你无论是修改、删除、新增,只有一个SaveChanges(),一定是只用一个链接,并且系统还会自动使用事务。

    2、查询

    增删改一个SaveChanges()就搞定了,可查询不是。

    同时需要查询多个数据的情况并不少见,比如EasyUI 的 DataGrid,它不仅要使用数据,还需要总行数,这时,就是两个查询,两个查询你虽然可以挨着写,可实际情况却是:

    打开连接

    查询

    关闭连接

    打开连接

    查询

    关闭连接

    具体这样影响多大性能不清楚,连接虽然在连接池中,但打开一次,应该是建立一次TCP连接,总要消耗一些性能。

    针对这种情况,就可以显示打开连接了:

    使用using或try,毕竟涉及到连接了吗,总要将它关闭,然后:

    .Open()

    查询

    查询

    .Close()或.Dis…()

    二、延迟加载

    不要使用延迟加载,要一次把需要的数据读取出来。特别是在循环中使用延迟加载,每次都读取一次数据库,对性能影响非常大。

    有主外键关系的使用.Include,没有的使用.Join。

    三、尽可能的使用.Select

    记得以前学数据库时,老师总是讲,用什么字段select什么字段,我想,这里应该也是一样,仅查询需要的字段,查询的字段少,在数据库执行查询时应该快一点,EF中应该也一样吧,字段少需要赋值的东西就少,应该也会快。

    至于select到新的实体类,还是到var,应该看复用程度和与其它功能(比如界面生成)的相关程度,如果仅用一次,var就很好。

    当然,如果需要传递,就不能使用var,要使用 dynamic。

    四、应用服务器查询还是数据库服务器查询

    直白点也就是先.ToList()还是后.ToList(),让然这里只是举例,只是想说明.ToList()才会到数据库查询,有些情况下并不需要.ToList()。

    这个个人认为还是应该在数据库服务器查询,比较好规范开发人员行为,因为有些数据量比较大,你不能都查询到应用服务器在select/where吧,这样可能性能更差。如果你应用服务器比较空闲,可以移到数据库中一个吗。当然有些老的应用,架子搭在那了,就需要视情况而定了。

    引用别人的文章来说明这个问题:

    http://www.cnblogs.com/jake1/archive/2013/04/25/3043664.html

    1. 分页的时候,尽量在数据库里面去分页.在我实际中的项目,我就发现我同事由于他不了解EF属性,它的分页都是做在内存中分页.下面请看他的代码.

             queryToList().Skip((pageInfo.PageIndex - 1) * pageInfo.PageSize).Take(pageInfo.PageSize);

             像上面的语句,他会先把数据从数据库中查出来,然后才分页.

              正确的写法应如下:

           query.Skip((pageInfo.PageIndex - 1) * pageInfo.PageSize).Take(pageInfo.PageSize).ToList();这样才会在数据库中分页.

    上面这个示例非常典型,无论怎样,分页都应该在数据库中,你把很多数据都读取到应用服务器的内存中再取其中的10条记录,真是有点小题大做了。

    五、太复杂的查询使用存储过程

    如果涉及多个表的关联,最好使用存储过程。EF虽然也能实现,但其生成的sql恐怕和预想的要差很远。

    六、主外键

    能使用主外键的,尽可能的使用主外键,这样无论是EF还是数据库,性能都会有所提高。当然太复杂的还是应该使用存储过程。

    七、预生成视图

    这个操作还很麻烦,当然只是第一次访问时会影响性能,对一些访问量不大的,不用也罢,毕竟你发布上去之后,有可能第一次访问的就是你自己。

    八、NoTracking

    image

    这个按微软说性能影响不大,多数情况下我们也不需要它跟踪,所以,加上算了。

    九、using

    image

    十、Exists

    在博客中看到的,感觉很有用

    http://www.cnblogs.com/lori/p/3457430.html

    EF架构~在ef中支持IQueryable级别的Contains被翻译成了Exists,性能可以接受!

    回到目录

    Entityframeworks很聪明

    不错,非常不错!ef里的contains比linq to sql里的contains有了明显的提升,事实上,是在进行SQL语句翻译上有所提升,在linq to sql里不支持iqueryable的contains集合,它只支持本地集合进行contains,而本地集合的contains会被.net翻译成sql语句是where in (...),即集合有多个元素,在in里就会被列举多少次,这个在性能上是非常低下的,不提倡的,而且它还有长度限制,最多本地集合在linq to sql里是2000多个元素。

    ef在这点上表示不错,它为了防止你使用低下的查询,它杜绝你在linq语句中去ToList()对象,这是不错的选择,对于EF中的contains的用法,我们一般是分两步,第一查询出要列举的结果集,但不要ToList(),第二是使用contains语句,当EF把它发到SQL端时,这个语句被翻译成了exist,我们知道,这种查询的性能一定是比where in强的,不说SQL本身就说网络传输,它也一定比前者省了不少,呵呵。

    Entityframeworks中正确使用Contains语句的Demo

    错误的

       var linq = (from data1 in GetUser().Where(i => i.UserID <= 50) select data1.UserID).ToList();
    
       var linq2 = GetUser_StudyRecord().Where(i => linq.Contains(i.UserID.Value)).ToList();

    SQL语句截图

    正确的

     var linq = (from data1 in GetUser().Where(i => i.UserID <= 50) select data1.UserID);//IQueryable<int>,一个查询计划
    
     var linq2 = GetUser_StudyRecord().Where(i => linq.Contains(i.UserID.Value)).ToList();

    SQL语句截图

    对我这种散修来说,未查找更多实用的,路过的老大看到有错误指点一下

  • 相关阅读:
    欧拉回路 定理
    UESTC 1087 【二分查找】
    POJ 3159 【朴素的差分约束】
    ZOJ 1232 【灵活运用FLOYD】 【图DP】
    POJ 3013 【需要一点点思维...】【乘法分配率】
    POJ 2502 【思维是朴素的最短路 卡输入和建图】
    POJ 2240 【这题貌似可以直接FLOYD 屌丝用SPFA通过枚举找正权值环 顺便学了下map】
    POJ 1860【求解是否存在权值为正的环 屌丝做的第一道权值需要计算的题 想喊一声SPFA万岁】
    POJ 1797 【一种叫做最大生成树的很有趣的贪心】【也可以用dij的变形思想~】
    js 实现slider封装
  • 原文地址:https://www.cnblogs.com/dotnetmvc/p/3735805.html
Copyright © 2011-2022 走看看