我写了很多的帖子关于orm,今天我还想再说一遍:在关键的高并发的Web应用程序中使用ORM工具,是在过去几年中软件阶级所做的最伟大的愚蠢架构。

sanguorewrite 2014-11-15 12:16:50
我写了很多的帖子关于orm,今天我还想再说一遍:在关键的高并发的Web应用程序中使用ORM工具,是在过去几年中软件阶级所做的最伟大的愚蠢架构。

WEB应用程序的瓶颈都在服务器的资源;内存和处理器的时间. 这些都是有特别高的成本。
让我们从0开始回顾一下一个http request是如何被处理的:

1.加载和初始化数据库的context,
2.把LINQ表达式编译转换成SQL语句,
3.发射SQL到服务器上 ,server 编译sql, 生成执行计划 ,优化查询,
4. 执行编译后的query,
5.转换结果为无类型的ADO数据集,
6. 生成有类型的ADO数据集,
7.使用反射 这种 最没有效率的方式 生成 实体 实例
8.从实体创建可序列化的对象,
9.创建XML或JSON对象,并将其传递到 output stream。

只有2个步骤是为任务(4和9)中的所有其他必要的 - 垃圾。考虑到EF(V3.5至少)会产生非常低效的查询与很多 子查询,这使得SQL服务器不得不一直工作在效率最低的模式。

建议:

使用LINQ to DataSet中(http://msdn.microsoft.com/en-us/library/bb386977.aspx)作为一种重量轻的工具Web应用程序。

使用LINQ to DataSet 你会得到少得多几乎相同的结果。而且还非常快.几乎是工业应用中最快的解决方案了.

当然, 对于小型数据库小型/个人网站我 使用LINQ to SQL /entity framework/ hibernate ... 或任何其他的ORM我想不是问题。
但是,对于专业网站,性能确实很重要,天下武功,唯快不破.

我学会了永远不要依靠一个ORM。纯粹的ADO,是唯一的答案,没有什么比它的性能更好了。当然这可能需要更长的时间来写DAL,但一旦这样做了,我相信我不会有任何其他的问题。

要知道,所有的ORM都有自己的问题,缺陷,性能问题和解决这些轻松的时间比任何时候我会用写纯SQL更多的时间。

当然,这是假定开发者能够编写DAL,并且有足够的智商来理解sql。 现实很简单,要么和orm一起完蛋,要么拿起了一本书,好好学习SQL。

学习SQL,绝对是个好主意,因为它似乎很多开发员甚至没有基本的SQL知识。你懂,你就赢了.

...全文
559 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
sanguorewrite 2014-11-16
  • 打赏
  • 举报
回复
狂赞! "所有的抽象都应该是需求驱动的,没有需求就没有设计,没有抽象。"
showjim 2014-11-16
  • 打赏
  • 举报
回复
引用 6 楼 sanguorewrite 的回复:
真正的封装是,经过深入的思考,做出良好的抽象,给出“完整且最小”的接口,并使得内部细节可以对外透明(注意:对外透明 的意思是 , 外部调用者可以顺利的得到自己想要的任何功能, 完全意识不到内部细节的存在; 而不是外部调用者为了完成某个功能、却被碍手碍脚的private声明弄得火冒三丈;最终只能通过怪异、复杂甚至奇葩的机制,才能更改他必须关注的细节——而且这种访问往往被实现的如此复杂,以至于稍不注意就会酿成大祸)。 一个设计,只有达到了这个高度,才能真正做到所谓的“封装性”,才能真正杜绝对内部细节的访问。 否则,生硬放进private里面的东西,最后还得生硬的被拖出来——当然,这种东西经常会被美化成“访问函数”之类渣渣(不是说访问函数是渣渣,而是说因为设计不良、不得不以访问函数之类玩意儿在封装上到处挖洞洞这种行为是渣渣)。
封装+透明 与 完整 只能是某个人的当前时概念,最多满足你个人的当前需求,既不可能满足他人需求,也不可能满足未来需求。 所有的抽象都应该是需求驱动的,没有需求就没有设计,没有抽象。 那种生硬的private属于过度设计,把门关起来,却留出一扇窗,这种行为与掩耳盗铃没有区别,只不过大多数人都被教条了。
sanguorewrite 2014-11-16
  • 打赏
  • 举报
回复
那个ooad的教徒过来看看,我想说的,大部分这个人2010年就说过了. http://www.tuicool.com/articles/Izummy http://javaforu.blogspot.ca/2010/12/what-they-did-not-teach-in-oopooad.html
sanguorewrite 2014-11-16
  • 打赏
  • 举报
回复
真正的封装是,经过深入的思考,做出良好的抽象,给出“完整且最小”的接口,并使得内部细节可以对外透明(注意:对外透明 的意思是 , 外部调用者可以顺利的得到自己想要的任何功能, 完全意识不到内部细节的存在; 而不是外部调用者为了完成某个功能、却被碍手碍脚的private声明弄得火冒三丈;最终只能通过怪异、复杂甚至奇葩的机制,才能更改他必须关注的细节——而且这种访问往往被实现的如此复杂,以至于稍不注意就会酿成大祸)。 一个设计,只有达到了这个高度,才能真正做到所谓的“封装性”,才能真正杜绝对内部细节的访问。 否则,生硬放进private里面的东西,最后还得生硬的被拖出来——当然,这种东西经常会被美化成“访问函数”之类渣渣(不是说访问函数是渣渣,而是说因为设计不良、不得不以访问函数之类玩意儿在封装上到处挖洞洞这种行为是渣渣)。
showjim 2014-11-15
  • 打赏
  • 举报
回复
首先内存成本并不高,如果真在意成本,64G的二手内存也就是一个实习生一个月的工资。 其次善用内存,使用数据缓存可以减少的人工成本绝对对得起它的价格。 数据查询,第一步是查询缓存数据,只有当缓存未命中的时候才查询数据库。 1.context对于ORM不是必须的。 2.需要编译转换的是LambdaExpression表达式,对于ORM来说它也不是必须的。不过一个好用的ORM应该使用LambdaExpression,这样的话确实有一点点性能开销。但是性能问题一般都可以抓大放小,比如这里的编译代价相对于数据库执行代价基本是可以忽略的,就好像一个10斤重的西瓜没必要因为少了一两而纠结。 3.在性能方面和第二点是同样的问题。 4.基于缓存查询的系统,执行同样的查询语言的概率是很低的。而如果使用SqlParameter模式来实现query重用需要的序列化操作,根据个人曾经的测试结果这个开销是可能大于简单的SQL解析的,当然这点开销也是没必要纠结的。 5.我现在所知道的ADO不论哪种方式返回的都是数据都是object,ORM使用DataReader并没有多余操作。 6.从DataReader转ORM仅仅需要new一个class,然后把object一次性强制转换成目标类型。而DataRow比一个单纯的class复杂得多,开销也大得多,每个数据每次使用最终都会涉及到类型转换,而且每次都得转,这样的数据对于缓存是不友好的。 7.反射对于ORM不是必须的,靠谱一点的ORM都应该是使用一次性反射委托或者EmitIL甚至代码生成技术。 8.强类型class的序列化比DataRow序列化高效得多,如果微软自带的序列化比DataRow开销大,你可以不用微软的序列化。 9.ORM配合web视图没有循环引用的问题,可以做到按需取值,而不是把整个DataRow中那些没用的数据都output到客户端。 也许你喷EF低效没问题,但是如果喷ORM低效就真是井底之蛙了,另外性能问题真不是几条SQL语句这么简单的事。 当然SQL是需要学习的,但是学习SQL的目的不是写SQL语句。而是要问自己ORM为什么这样处理?有没有更好的解决方案?而不是做一个无脑喷。
  • 打赏
  • 举报
回复
ORM为了解决程序开发中处理的对象格式与关系数据库的数据零散格式之间的“阻抗不匹配”问题。当然它可以集成一些近些年最新的框架知识,但是它肯定不是单纯地为了得到“最高操作效率”的目的的。你永远都能用低级的手段得到“最高操作效率”。所以没有谁在使用EF的时候禁止你同时使用ADO.NET。 你想到一个sql表达式可能非常复杂的时候,你肯定需要同时使用ADO.NET和EF两个版本来进行研究。而一般来说,新手几乎都会感兴趣于EF,这是你阻挡不了的。这就好像有人强调c语言程序如果写得好的话、永远都比c#程序(可能)运行得更快,然而我们其实都知道c程序员做现代高级语言的程序猿的工作是多么慢、项目缺乏扩展张力。 一个ORM并不需要每一次运行都翻译sql语句,它可以仅仅翻译一次然后就重复使用,甚至可以把上一进程的翻译结果保存到当前磁盘中让下一个进程在启动时先读取。同样地,就算EF是反射的(而实际它是自动生成代码的),那么也仅需要反射一次然后就把内存中生成的操作过程做为委托而重复调用。 我不用EF主要有两个原因。其一是因为它不能直接支持多态,其二是因为以前它不支持CodeFirst模式(现在也不太给力)。不过我认为它一直在改进。只不过我现在不用关系数据库了,一直没有精力去研究其编程的最佳实践、性能陷阱而已。 EF应该提供更多更好的编程实践,来避免一些容易滥用的陷阱。但是对于 .net 程序员而言,应该知道的关于性能的东西很多(例如善用缓存、业务架构设计、前端编程而不是服务器编程,等等),把一切性能问题都归咎到查询数据库的几条代码上,这其实可能是在事业上的一个“没有发展”的表现。
by_封爱 2014-11-15
  • 打赏
  • 举报
回复
我虽然不懂orm 还是什么ef 不过 我一直觉得ado.net 里面的还不错....
winnowc 2014-11-15
  • 打赏
  • 举报
回复
需要的是我们对框架和业务场景的深刻理解,做到有目的的选择技术,而不是盲目的跟随潮流。在对orm框架和sql都有比较深入的理解后才能真正达到提高性能的目的。否则可能手写的sql有时候还没有orm快,或者用orm却不知道它慢在哪里。 在有些应用场景,可能仅仅关掉EF的ChangeTracking就能够满足性能的需要了,如果是这种情况,手写DAL就得不偿失。part-1part-2是两篇orm查询性能的比较,可以看到对于EF,是否ChangeTracking的巨大差异。如果要用EF,它的性能注意事项,或者中文版(没有更新到EF6)必须要看明白。 当然EF可能会产生低效的sql,在更高的性能要求下,需要手动控制的时候用micro-orm框架会是一个性能和生产力的很好的平衡点,比如Dapper。自己写sql,它帮忙支持参数化查询,和结果的实体映射(或者dynamic方式),效率非常高。关于LZ说的第7步,实际上orm框架都不是用反射来创建实体的,那样的性能不可接受,而是用emit il的方式,它产生的il执行效率不会比手写的慢。 另外还存在一种问题,有些人对性能的追求不是来自业务场景的需要,而是出于自己对系统精确控制的感觉的需要或是为了体现自我价值。把自己关注的一个点的性能提到很重要的位置,却故意忽视了系统的真正瓶颈。这是比单纯的技术选择带来的影响更可怕。
wjq 2014-11-15
  • 打赏
  • 举报
回复
大部分同意,但高并发的web应用如果全都是对数据库的直接访问,也一样是愚蠢的吧。真正高并发下所有数据操作都直接对数据库操作,也绝对会有问题。orm带来的好处,通过ADO访问数据库各有各的好处,应该具体应用场景具体分析,不能一概而论吧
DotNetCoding(http//www.dotnetcoding.net)是一款帮助开发以数据库为基础,以DotNet为开发语言的Case开发工具。它集系统设计,代码自动生成等功能于一体 系统运用分层原理和组件原理,将所有的基于数据库访问的系统划分为用户界面层(UI),业务规则层(BLL), 数据访问层(DAL)和数据库层(DB). 每一下层为上层提供支持,一般不跨层访问,是一个真正意义上的多层架构; 同时结合现在一些已经成熟的设计框架,设计模式和构件模式,将一个解决方案分解为6个Project. 分别是通用类库, 通用控件库, 数据访问工程, 业务规则工程,项目专用控件工程,UI界面工程.整个方案根据已经设计好的数据库自动生成,在生成的过程种可以灵活的定义生成参数. 系统实现了比较完整的O-R映射.数据库的所有逻辑对象表,列,字段,主键,外键,Null, Default,唯一索引都在类里得到了体现,同时还支持代码表,代码列,自增长机制. 系统支持完整的数据操作功能,支持带事务功能的数据操作,提供数据自动装载功能,有很强的数据查询功能. 系统采用强类型来进行代码的生成,并且对最终开发人员的强类型支持很好,从而减少在编码过程引入的错误,为编高质量的代码提供了强有力的支持. 系统也比较充分的考虑了变更与维护的需要,在数据库设计发生变化的情况下,只要在已有工程的基础上重新生成一遍,系统就会自动合并最终开发编的代码到生成的代码,使系统的变更变的很容易. UI界面层按到组件原则来进行代码的自动生成.自动生数据编辑,数据显示控件,页面组合组件,并采用控件和CSS技术,由于采用了这些组件技术,使得最终开发人员可以很方便的变更自动生成的界面样式; UI界面应用MVC模式,将这个UI界面代码部分分为三部分:视图部分,模型部分和控制,自动生成Data Source属性来完成view和Model的相互映射;并且能按照功能组生成菜单, 同时系统能自动完成null, PK ,UK等基本的数据检验和基于单表数据的增删查改等基础功能. 此系统还提供了文档生成,数据库迁移与转换及部分设计有关的功能 现在此平台支持多种数据访问框架(三层框架, PetShop框架,工厂框架, WebServeice框架) 支持Windows , Web两种应用类型 支持VB.net , c#.Net两种开发语言 支持SqlServer, Oracle, Access等多种数据库, 并且支持用SqlServer数据库来进行数据模式的设计,而实际开发运行数据库是其他数据库的情况, 开发的应用可以非常轻松的变换数据库. 本系统的应用范围:有数据库访问功能的.net应用 应用前提:需要有已经设计好的数据库 采用此平台来开发信息管理系统, 能够直接将设计转化为代码,并支持系统的重构;最终开发人员一般只需要在业务规则层扩展相关业务规则的编码,对自动生成的界面进行少量的调整,在UI界面工程里添加少量的控制代码. 采用此开发平台,能够复用成熟的开发架构,自动生成所有非商业有关的代码,在公司范围内不断的积累开发技能和经验,极大的提高开发效率,规范开发,提高开发质量。
适合人群: 1、具有一定Python语言基础,有一定的web前端基础,要深入学习Python Web框架的朋友; 2、学习完“跟着王进老师学开发Python篇”“跟着王进老师学Web前端开发”的朋友; 3、有Django基础,但是学习企业级项目实战的朋友; 4、喜欢 Django 框架并深入研究的朋友; 5、有一定的数据库基础   课程目标:本系列课程是从零基础开始并深入讲解Django,最终学会使用Django框架开发企业级的项目。课程知识点全网最详细,项目实战贴近企业需求。本系列课程除了非常详细的讲解Django框架本身的知识点以外,还讲解了web开发所需要用到的技术,学完本系列课程后,您将独立出一个具有后台管理系统,并且前端非常优美实用的网站。   课程内容:在人工智能大行其道的时代,许多开发者对Python这门编程语言都比较熟悉。但是如何用它实现一个企业级别的项目,可能许多朋友还存在一些困惑。联科教育“跟着王进老师学Python”系列课程是专门针对要从事Python Web开发的朋友而准备的,并且按照企业需求的标准定制的学习路线。学习路线包含Python基础和进阶、Web前端、MySQL数据库、Flask和Django框架以及N多个企业真实项目。在学习完本系列所有的课程后,从前端页面的实现,到后台代码的编,再到数据库的管理,一人可以搞定一个公司网站的事情,掌握实现全栈开发,让你升职加薪不是梦! 本季课程介绍了DjangoORM模型,使用ORM模型的优势;DjangoORM模型常用的字段,ORM实现数据查询;Django后台管理等。所有应用均通过案例“在线图书商城”完成讲解和演示,完整项目,贯穿全部知识点,边学边练,帮助大家快速掌握知识,了解企业要求。

13,190

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 分析与设计
社区管理员
  • 分析与设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧