简而言之,我同意您的CTO。您可能已经牺牲了可伸缩性而获得了一些性能(如果这些术语令人困惑,我将在下面进行说明)。我最担心的两个问题是可维护性和缺少水平扩展的选项(假设您将需要此功能)。
接近数据: 让我们退后一步。将代码推送到数据库中有一些很好的理由。我认为最大的是接近数据-例如,如果您期望计算返回少量值,但是这些是数百万条记录的汇总,则按需发送数百万条记录(按需)要在其他地方聚合的网络非常浪费,并且很容易杀死您的系统。话虽如此,您实际上可以通过其他方式实现数据的接近性,本质上是使用缓存或分析DB(其中一些聚合是预先完成的)来实现的。
数据库中代码的性能:诸如“执行计划缓存”之类的次要绩效影响则更难辩驳。有时,如果缓存了错误的执行计划,则缓存的执行计划可能是非常不利的事情。根据您的RDBMS,您可能会从中获得最大的收益,但是在大多数情况下,参数化的SQL并不会带来太多好处(通常也会缓存这些计划)。我还要指出,对于基本操作和非关系编程(字符串操作,循环等),大多数已编译或JIT编辑的语言通常比SQL等效语言(例如T-SQL或PL / SQL)性能更好,因此您不会如果您使用Java或C#之类的方法进行数字运算,那么这里不会丢失任何东西。细粒度的优化也非常困难-在数据库上,通常,您只能使用通用B树(索引)作为唯一的数据结构。公平地讲,完整的分析(包括诸如具有更长运行时间的事务,锁升级等)可能会填满书本。
可维护性: SQL是一种设计出色的语言。我不确定这是否适合应用程序逻辑。使我们的生活可以承受的大多数工具和实践(TDD,重构等)都难以应用于数据库编程。
性能与可伸缩性:为了澄清这些术语,我的意思是:性能是指假设低负载的情况下,您期望单个请求通过系统(并返回给用户)的速度。这通常受到诸如经过的物理层数,这些层的优化程度等因素的限制。可伸缩性是性能随着用户/负载数量的增加而变化的方式。您可能具有中等/低性能(例如,一个请求需要5秒以上的时间),但是性能却很棒(可以支持数百万个用户)。在您的情况下,您可能会体验到良好的性能,但是可伸缩性将受到您可以物理构建的服务器规模的限制。在某个时候,您将达到该极限,并被迫转向分片之类的东西,根据应用程序的性质,这可能不可行。
过早的优化: 最终,我认为您犯了过早优化的错误。正如其他人指出的那样,您实际上并没有度量来显示其他方法的工作方式。好吧,我们不能总是建立完整的原型来证明或反驳理论。但是总的来说,我总是不愿意选择一种以可维护性(可能是应用程序最重要的质量)为代价的方法。 。
编辑:从积极的角度看,垂直缩放在某些情况下可能会延伸得很远。据我所知,SO在单个服务器上运行了相当长的时间。我不确定它如何与您的10,000个用户匹配(我想这取决于他们在系统中执行的操作的性质),但是它使您对可以执行的操作有所了解(实际上,更令人印象深刻的例子,这恰好是一个人们可以轻易理解的流行)。
编辑2:澄清和评论其他地方提出的一些事情:
- 回复:原子一致性-ACID一致性很可能是系统的要求。上面的内容并没有真正反对这一点,您应该意识到ACID一致性并不需要您在数据库中运行所有业务逻辑。通过将不需要存储在数据库中的代码移动到数据库中,您将不得不在其他数据库的物理环境中运行-它正在与数据库的实际数据管理部分争夺相同的硬件资源。至于仅将代码扩展到其他数据库服务器(而不是实际数据)-当然可以,但是在大多数情况下,除了额外的许可成本之外,您在这里还能得到什么?将不需要的东西放在数据库之外。
- 回复:SQL / C#性能-因为这似乎是一个有趣的话题,所以让我们在讨论中多加一些。您当然可以在数据库中运行本机/ Java / C#代码,但据我所知,这不是这里讨论的内容-我们正在比较以T-SQL之类的典型应用程序代码与C#之类的典型应用程序代码的实现。过去,使用关系代码很难解决许多问题-例如,考虑“最大并发登录数”问题,其中有记录表明登录或注销以及时间,并且您需要确定一次最多可以登录的用户数是。最简单的解决方案是遍历记录,并在遇到登录/注销时保持计数器递增/递减,并跟踪该值的最大值。可以,我不知道),您能做的最好的事情就是CURSOR(纯关系解决方案的复杂度都不同,尝试使用while循环解决它会导致性能降低)。在这种情况下,是的,C#解决方案实际上比您在T-SQL期间所能达到的速度更快。这似乎有些牵强,但是如果您要处理代表相对变化的行,并且需要计算这些变化的窗口汇总,则此问题很容易在金融系统中显现出来。存储的proc调用也往往会更昂贵-调用一个普通的SP一百万次,并查看与调用C#函数相比如何。我在上面提到了其他一些示例-我还没有遇到任何人在T-SQL中实现适当的哈希表(实际上可以带来一些好处),尽管在C#中很容易做到。同样,DB擅长做某些事情,而DB却不那么擅长。就像我不想在C#中进行JOIN,SUM和GROUP BY一样,我也不想在T-SQL中编写任何特别占用CPU的内容。