声明:
本文是一篇有争议的文章,甚至有可能是一篇争议非常大的文章,可能争来争去依然无法得到一个统一的意见。
场景
个别公司的技术决策者要求团队的开发人员在编写数据访问层的时候,禁止在程序中出现任何的SQL语句,禁止使用Entity Library,禁止使用NBear、NHibernate、IBatis、Entity Framework等ORM框架,只允许使用存储过程。试想一下,您的公司是否是这样子的?您的身边有没有这样的朋友,他们的公司存在这样或类似这样的情况吗?
矛盾点
对于开发人员来说,使用存储过程的话,工作量比以前要大很多,而且涉及到表的字段更改,项目重构也是个非常麻烦的问题,使用ORM很方便就可以实现数据的CRUD功能,多表操作也非常的容易,原来写很少的代码就可以操作数据,现在却要写很多的代码。本来公司给的时间就短,项目紧,现在这么一搞,工作量一下就增加了不少,再者,如果需求一旦发生变化,不可避免的数据库就得增加或修改某些字段,相应的存储过程跟数据访问层的方法都得做调整,开发人员的日子不好过了。
对于公司的决策者来说,性能问题是不可以妥协的,无论付出多大代价,既然做出了决定,那么就没什么好讨论的。
结果
结果可想而知,最终是按照决策者的决定,开发人员加班加点的做开发,既然决策者都已经做了决定,似乎再讨论用不用存储过程就是一个非常敏感的话题,再讨论类似的问题的话,开发人员所面临的处境就可能是尴尬的,在某些公司甚至是危险的。无论怎样,开发人员可能最终都很难改变决策者的决定。
决策者的心声
带着这些疑惑,我跟多位决策者进行沟通,搜集了他们的意见,总结下来的话,大概就是以下几点:
- 性能问题。经过测试,使用ORM比直接调用存储过程慢10倍。如果是做软件项目或软件产品,使用ORM问题不大,可是如果是以运营为主(访问量较大)的Web网站,性能上就会有问题。
- 并发问题。一旦访问量较大并且达到一定数量级的时候,ORM就可能会出现并发问题。
- DBA的能力受限。一旦出现性能问题,如果是按照写存储过程的方式来做,公司可以招来技术实力强的DBA直接改存储过程进行优化,而如果是使用ORM的话,那么DBA就很难进行优化,因为DBA很难读懂ORM写的程序,更不知道ORM内部的实现方式,这样一来,DBA的能力就得不到施展。
- 不愿意被微软绑架。以Entity Framework为例,Entity Framework不是开源的,如果出现性能问题,不能够看到源代码,这可能是一个风险。再者,一个强有力的公司强有力的团队,如果没有自己的技术,总是使用微软的不开源的框架,这怎么可以?
- Entity Framework是微软的产品,微软的产品只适合中小型的公司做开发,大的互联网公司是不敢用的,甚至他们可能采用Java+Oracle来做,一旦达到一定数量级,微软的东西就可能会出现问题。
笔者的心声
在充分理解了决策者的心声以后,我思绪万千,心中久久不能平静。终于,在把很多东西看淡,抛开杂念,在这样一个宁静的夜晚,也坦诚的把我的想法一一阐述,分别针对决策者的心声,谈一谈我的个人看法。
1.到底什么是性能问题?存在不存在性能问题?
来看下测试是如何做的,使用存储过程进行插入或删除操作,分别使用存储过程和Entity Framework,循环10000次或者1000000次操作,然后整体上存储过程要比使用Entity Framework要快10倍。实际场景是怎样的呢?
实际的场景是用户点击页面上的按钮,执行了1次操作,我们假定按照写存储过程的方式来做,用户这1次操作可能需要0.001秒,而使用Entity Framework要慢10倍,用了0.01秒,那么这0.001秒比0.01秒的确是快10倍,但是对用户来说,可能根本就没有明显的差距,因为这么微弱的时间用户是体会不出来的。我们开发的程序,对用户来说,我们的产品会不会因为这0.001秒跟0.01秒的差距而打折扣呢?这微弱的差距是严重性能问题?还是可以忽略不计?
2.到底存在不存在并发问题?
诚然,可能之前有团队使用ORM开发高并发的项目,他们在运营中出现了并发问题,可是DBA又无法查出来到底是什么地方导致了并发问题,最终把一切的一切归咎在ORM上。
亲爱的朋友们,让我们理智的冷静的来分析下两者的技术实现上的不同吧。
直接调用存储过程:打开数据库连接--》执行编译好的数据库语句--》关闭数据库连接
ORM:打开数据库连接--》把对象解释成SQL语句--》执行SQL操作--》关闭数据库连接
通过比对我们可以发现,ORM就可以比作是一个SQL生成器,它把对象解释,拼一个SQL语句出来,然后在执行这个SQL语句,由于还需要解释,就相当于多了一步翻译的工作,因此,就比存储过程慢了一点点,那么慢的这一点点会不会出现并发问题?我的意见是并发问题多半是由于锁的影响,只要不产生锁,就不会有并发问题。正因为如此,高并发的项目开发,多半是忌讳使用事务,有的程序员手写异常后的数据库回滚语句(有些滑稽哈,但事实上就是这样),项目中也不推荐使用游标跟触发器。
3.DBA能力受限。诚然,DBA看不懂ORM写的程序,更加不明白ORM内部的实现原理。但是,DBA是可以跟程序员配合,利用SQLProfile等工具,看到最终SQL语句是如何执行的。也就是说,DBA的能力也是依然可以发挥出来的,只不过是需要跟程序员配合而已,或者DBA需要熟悉如何调试、跟踪。如果说全部写存储过程了,DBA能力是放开了,可是程序员的能力就受限了,譬如说,在进行大批量的数据插入的时候,大家都知道,.ADO.NET2.0的一个新特性SqlBulkCopy是多么的快,估计这是DBA无法优化的。对SqlBulkCopy不熟悉的朋友,请参考《SQLServer中批量插入数据方式的性能对比》。
很多时候,一个软件性能的优化,需要从整体去考虑,并不一定是说出现数据库性能问题,就一定是DBA的责任,或者说一定是程序员的责任。在DBA跟程序员之间难道就真的像插销跟插板之间那样,职责分的特别的清楚?很多时候我们得充分利用存储过程的特性,跟.NET平台的一些优良特性,选择适合我们的来进行开发,没有什么是最佳的,但是对我们来说,适合我们就好。
从另外的角度考虑,其实在项目初期,DBA就应该参与进来,进行数据库的设计了,而一旦数据库设计好了,设计得并不规范,存储过程也些了成千上万了,将来一旦出现性能问题,相信也够DBA喝一壶的。
4.不愿意被微软绑架。这个观点倒是让我感觉到意外,至少我们很多都在用微软的.NET Framework,我们使用微软的SQL Server数据库,如果说我们被绑架,可能现在就已经被绑架了,SQLServer的存储过程跟Oracle、Mysql的存储过程是不一样的,如果将来进行数据库的迁移,那么可想而知后果是怎样的。到底怎样才是真正的被绑架?
5..Net与Java孰好孰坏?
关于这个问题的讨论,一直就是个无休止的讨论。scottgu把这个比作是“带有宗教性质的技术争论”。诚然,讨论这样的问题的确令人讨厌,而且是浪费时间,而且讨论的双方都深切的关注着。讨论来讨论去最终也不会有结果。
在目前所运行的软件系统中,我们可以看到其背后的平台、语言等是各种各样,MySpace是基于.NET平台的,淘宝网是基于Java的,而Google则推崇使用Python,许多大型的电力系统还依然运行在C++平台上,最关键的一点,.NET并不是没有在大型项目中应用。只不过是Java起步早,.NET起步晚而已,要在前几年,Java做的大型项目的确是比.NET的大型项目要多。
很多时候,即使是使用相同的开发语言,不同的程序员开发的程序效率就差30倍以上,甚至几千倍以上,这点好不夸张。诚然,每门技术自有其缺点,但它们也都自有其优点,如果它的优点恰好能符合你的需要,用它就好了。重要的是,你有没有使用好它的能力。
总结
其实总结就不必了,说点题外话吧。存储过程在单条执行操作的时候,的确要比使用ORM要快,可是如果是执行批量的操作,使用存储过程就会非常的费劲。之前我是这样做的。假定更新1000条数据,数据库里只有2个字段,循环调用1000次存储过程需要2分钟左右,当时我把要更新的id以参数的形式逗号分隔传入存储过程,在存储过程中循环执行1000条数据,发现时间跟循环调用1000次存储过程的时间是差不太多的,最终进行了改进,改进的方法嘛,还是把要更新的Id以参数形式逗号分隔传入存储过程,然后使用update table set value=’value’ where id in select id in 分隔函数(id1,id2,id3…..),经过这种方式,更新1000条数据的时间从2分钟变成了200毫秒,可是问题依然不完美,方法存在局限性。
首先,使用这种方法参数的长度是有限制的,varchar类型最大不超过8000,nvarchar类型最大长度不超过4000.
其次,如果表中有多个列,要更新的也是多列,存储过程的局限性就出来了。
再次声明:文中观点仅代表个人观点,如果您有不同意见,欢迎共同讨论。
最后,给大家分享个幽默视频,来缓解下这种紧张而激烈的争论吧。
分享到:
相关推荐
本文档将讨论识别并解决在Linux、Unix、Windows(LUW)及z/OS平台上运行的DB2中最常见的性能瓶颈的方法,并比较和对比这些平台上应用程序的内存架构、物理设计、维护和SQL调优技术。 #### 定义性能 性能是指数据库...
这些指标有助于识别性能瓶颈。 3. **报警机制**:当某些关键指标超过预设阈值时,MySQLMTOP会触发报警,提醒DBA及时采取措施,防止故障发生。 4. **历史数据记录与分析**:工具保存了过去一段时间内的性能数据,...
例如,异常值测试可以检查数据库处理异常情况的能力,压力测试则能揭示数据库在高负载下的性能瓶颈。同时,备份和恢复测试确保在数据丢失或系统故障时,能够准确无误地恢复数据。 在进行数据库测试时,我们还需要...
分析结果可以帮助识别性能瓶颈,优化系统性能,并确定系统在特定负载下的容量。 在《LoadRunner性能测试实战教程》中,读者将学习到如何设置测试环境,创建和优化Vuser脚本,设计和执行测试场景,以及如何分析和...
数据库连接池是现代应用程序开发中的一个关键组件,它在提高数据库访问效率、节省系统资源以及管理数据库连接方面扮演着重要角色。C3P0 是一个开源的 Java 数据库连接池实现,它为 Java 应用程序提供了高效且可扩展...
随着互联网和大数据时代的到来,传统的基于SQL的关系型数据库在处理海量数据时遇到了挑战,如扩展性差、性能瓶颈等问题。NoSQL数据库应运而生,其主要特点是高可扩展性、高并发性和高可用性。 NoSQL数据库的核心...
1. **监控指标**:MySQL Monitor通常会提供一系列关键指标,如查询速率、连接数、缓存命中率、锁等待、磁盘I/O等,这些数据有助于评估数据库性能瓶颈。 2. **性能分析**:通过监控SQL查询的执行时间,可以找出慢...
通过监控数据库性能指标,可以识别瓶颈并采取相应措施。例如,合理使用索引可以显著提升查询速度,而调整数据库缓冲池大小则可能改善内存使用效率。 八、高可用性和灾难恢复 DB2支持集群、镜像、复制等多种高可用性...
标题中的"C#.Net(EF+MVC+Bootchart)后台框架源码带数据库.7z"揭示了这个压缩包包含的是一套基于C# .NET技术栈的后台框架,使用了Entity Framework(EF)作为数据访问层,ASP.NET MVC作为Web应用程序的模型-视图-控制...
9. **性能监控与分析**:通过工具如Application Insights进行性能监控,找出瓶颈,针对性地进行优化。 10. **CDN服务**:使用内容分发网络(CDN)可以加速静态资源的加载,减轻服务器压力。 总结来说,打造高性能...
7. **性能诊断**:学习如何识别和解决性能问题,包括等待事件分析和性能瓶颈定位。 8. **数据库并发控制**:理解锁、多版本并发控制(MVCC)和事务管理对性能的影响。 9. **存储体系结构**:了解磁盘I/O对数据库性能...
在高并发的游戏环境中,数据库连接池是必不可少的,它管理数据库连接的创建、分配、回收,避免频繁的连接建立和关闭,提高数据库访问效率。Druid 还提供了强大的监控功能,如SQL解析、执行性能分析,帮助开发者定位...
6. **故障排除**:要求考生能够识别并解决常见的数据库问题,如锁定、死锁、性能瓶颈等。 1Z0-042.exe 文件很可能是一个包含模拟考试软件的可执行文件,考生可以通过运行此文件来访问模拟器并开始练习。使用过程中...
自动数据库管理系统(ADDM)是Oracle的一项智能诊断工具,它定期收集数据库性能统计数据,并生成报告,帮助DBA快速定位性能瓶颈,提供优化建议。 ### 使用恢复管理器(Using Recovery Manager) RMAN不仅用于备份...
在使用Java、SQLJ与DB2进行数据库访问时,可能会遇到各种性能瓶颈。这些问题通常与查询优化、索引设计、缓存策略等因素有关。为了避免性能问题,开发者需要遵循最佳实践指南,比如合理的索引设计、优化查询逻辑等。 ...
而跟踪文件则用于记录特定后台进程或用户的活动信息,对诊断系统问题、性能瓶颈或调试应用程序非常有用。控制这些日志和跟踪文件的生成与存储是优化过程中的一个重要组成部分。 实用程序和动态性能视图则为DBA提供...
例如,pg_stat_activity视图可能提供了更多的统计信息,帮助识别阻塞和性能瓶颈。 8. 兼容性与互操作性:PostgreSQL 11.18可能提高了与其他数据库系统(如Oracle或MySQL)的数据迁移工具的兼容性,使得数据迁移更加...
同时,通过SQL*Plus、Enterprise Manager Console等工具,可以进行性能监控,识别性能瓶颈,并使用索引、分区、SQL优化等手段进行调优。 数据库安全性是另一个重要主题,包括用户管理、权限控制和审计。Oracle 10g...
根据给定的文件信息,我们可以深入探讨Oracle数据库管理和性能优化的关键知识点,特别是针对1Z0-043考试中涉及的题目与概念。 ### 数据库缓冲区大小调整 在第一题中,面对数据库性能随时间逐渐下降的问题,调查...