RedBean ORM performance


RedBean ORM performance

我想知道Redbean ORM是否可以用于面向性能的场景,如社交网络web应用程序,即使多个用户同时提取数千个数据,它是否稳定。我还想知道Redbean是否消耗更多的内存空间。

谁能提供一个Doctrine-Propel-Redbean的比较研究?

我觉得Tereško的答案不太对。

首先,它没有解决原来的问题。这确实是一个反对orm的案例,我同意他在回答中描述的问题。这就是我写RedBeanPHP的原因。仅仅因为大多数orm不能使您的生活简单一点,并不意味着对象关系映射系统的概念是有缺陷的。大多数orm试图隐藏SQL,这就是join变得如此复杂的原因;他们需要在面向对象的环境中重新发明类似的东西。这就是RedBeanPHP的不同之处,因为它不隐藏SQL。它创建易于查询的可读、有效的SQL表。RedBeanPHP没有使用虚构的查询语言,而是使用普通的旧SQL进行记录和bean检索。简而言之,RedBeanPHP与SQL一起工作,而不是反对它。这使得它不那么复杂。

是的,RedBeanPHP的性能很好。我怎么能这么肯定?因为与其他orm不同,RedBeanPHP区分了开发模式和生产模式。在开发周期中,数据库是流动的;您可以添加条目,它们将被动态添加。RedBeanPHP创建列、索引、猜测数据类型等。如果一段时间后需要更多字节(更高的数据类型),它甚至可以扩展列。这使得RedBeanPHP非常慢,但只有在开发期间,速度不应该是一个问题。一旦您完成了开发,您就可以使用单个模式说明符R::freeze()来冻结数据库,并且不再进行检查。剩下的就是生产服务器上的一个非常简单的数据库层。因为没有做太多,所以性能很好。

是的,我知道,我是RedBeanPHP的作者,所以我有偏见。然而,我觉得我的ORM和其他ORM是一样的,这促使我写了这篇文章。如果您想了解更多,请随时咨询RedBeanPHP网站,这里有关于性能的讨论。

在我们公司,我们将RedBeanPHP用于嵌入式系统和金融业务系统,因此它的可扩展性似乎相当好。

我和RedBeanPHP社区一起真诚地努力使ORM世界变得更美好;你可以在这里阅读任务声明。

祝你的项目顺利,我希望你能找到你正在寻找的技术解决方案。

@tereško如果可能的话,你能根据你的经验给出关于纯SQL的形式的优点和缺点吗?同时我也会在谷歌上搜索这个话题。——贾森·贾斯特斯

好. .用600个字符来解释这一点是很困难的。

有一件事我必须澄清:这是关于PHP中的 orm,尽管我很确定它也适用于一些Ruby orm,也许还有其他orm。

简而言之,你应该避免它们,但是如果你不得不使用ORM,那么你最好使用原则2。X,它是较小的恶。(实现类似于DataMapper的东西,而不是ActiveRecord)。

针对orm的案例

一些开发人员喜欢使用ORM的主要原因也是它们最糟糕的地方:在ORM中很容易做简单的事情,并且性能成本很小。这很好。

1。指数复杂性

问题的根源在于人们喜欢用同样的工具做任何事情。如果你所有的是一个锤子(…)类型的问题。这会导致产生技术债务。

首先,编写新的DB相关代码很容易。也许,因为你有一个大项目,在头几周的管理(因为以后可能会出现其他问题——如果对细节感兴趣,请阅读The myth Man-Month)决定雇用更多的人。你最终会更喜欢有ORM技能的人,而不是普通的SQL。

但是,随着项目的进展,您将开始使用ORM来解决越来越复杂的问题。你将开始破解一些限制,最终你可能会遇到即使用你知道的所有ORM破解也无法解决的问题……现在你没有SQL专家,因为你没有雇佣他们。

此外,大多数流行的ORM都实现了ActiveRecord,这意味着您的应用程序的业务逻辑直接耦合到ORM。由于这种耦合,添加新功能将花费越来越多的时间。出于同样的原因,为它们编写好的单元测试是极其困难的。

2。性能

我已经提到,即使简单使用ORM(使用单个表,没有JOIN)也会有一些性能成本。这是因为他们使用通配符*来选择数据。当您只需要文章id和标题的列表时,没有必要获取内容。

当您需要基于多个条件的数据时,

orm在处理多个表时确实很糟糕。考虑这个问题:

数据库包含4个表:Projects, Presentations, SlidesBulletpoints

  • 项目有很多演示
  • presentation have many Slides
  • 幻灯片有许多公告

并且您需要从与id为2,4和8的Projects相关的4个最新Presentations中找到标记为"重要"的Slides中的所有Bulletpoints中的内容。

这是一个用纯SQL编写的简单JOIN,但是在我所见过的任何ORM实现中,这将导致3级嵌套循环,每个级别都有查询。


注:还有其他原因和副作用,但它们相对较小。现在想不起其他重要的事情了。

我在这里与@tereško不同- orm可以使数据库查询更容易编写和维护。在我看来,有一些伟大的工作正在推进和学说-利用他们!网上有很多性能比较,也可以看看NotORM(我没有用过,但是如果我没记错的话,他们和Doctrine做了一些比较)。

如果您达到了吞吐量需要执行原始SQL的点,那么在该点进行优化。但是从减少bug数量和提高生产力的角度来看,我认为节省下来的钱可以用来购买更好的服务器。当然,你的情况可能会有所不同。

顺便说一句,我不知道RedBean,但我温和地认为,在大多数情况下,Propel比Doctrine更快,因为这些职业是预先生成的。当我使用Propel作为唯一的选择时,我一直坚持使用它,尽管我当然不会反对使用Doctrine。

2018

更新

多年后,Propel 2仍处于alpha阶段,需要大量的大型重构项目,遗憾的是,这些项目还没有完成。尽管维护者说这个alpha版本很适合在生产环境中使用,因为它有很好的测试覆盖率,他们现在已经开始开发Propel 3了。不幸的是,在我写这篇文章的时候,它实际上还没有任何版本,尽管这个存储库已经有一年的历史了。

虽然我认为Propel是一个伟大的项目,但我想知道目前是否最好使用其他东西。它还可以从灰烬中重生!

我会选择"Horses for Courses"的情况,它利用了两个世界的混合和匹配。我已经用RedBean构建了几个大型应用程序,所以我的评论将完全集中在RedBean上,而不是其他orm。

红豆慢吗?

嗯,这取决于你如何使用它。在某些情况下,它比传统查询更快,因为RedBean将结果缓存几秒钟。重用查询将更快地产生结果。使用R::debug(true);查看日志,它总是显示

"SELECT * FROM `table` -- keep-cache"

场景1:抓取所有(*)

在RedBean中如果你查询

$result = R::findOne('table', ' id = ?', array($id));

表示为

$result= mysql_query("Select * from TABLE where id =".$id);

你可能会说,如果表有多列,为什么要查询(*)

场景2:单柱

获取单个列

R::getCol( 'SELECT first_name FROM accounts' );

就像我提到的"马为课程",开发人员不应该简单地依赖FindOne, FindAll, FindFirst, FindLast,而是要仔细起草他们真正需要的东西。

场景3:缓存

当你不需要缓存时,你可以在应用程序级别禁用,这不是一个理想的情况

R::$writer->setUseCache(true);

RedBean建议,如果你不想在应用程序级别禁用缓存,你应该使用传统的无缓存参数查询,如$result = R::exec("SELECT SQL_NO_CACHE * FROM TABLE");

这完美地解决了从表中获取实时数据的问题,完全放弃了查询缓存。

场景4:快速发展

使用ORM使你的应用程序开发非常快,开发人员可以使用ORM编写代码比编写SQL快2-3倍。

场景5:复杂查询&关系

RedBean提供了一种非常好的实现复杂查询和one-to-manymany-to-many关系的方法

用于复杂查询的纯SQL

$books = R::getAll( 'SELECT 
    book.title AS title, 
    author.name AS author, 
    GROUP_CONCAT(category.name) AS categories FROM book
    JOIN author ON author.id = book.author_id
    LEFT JOIN book_category ON book_category.book_id = book.id
    LEFT JOIN category ON book_category.category_id = category.id 
    GROUP BY book.id
    ' );
    foreach( $books as $book ) {
        echo $book['title'];
        echo $book['author'];
        echo $book['categories'];
    }

OR RedBean处理多对多关系的方法

list($vase, $lamp) = R::dispense('product', 2);
$tag = R::dispense( 'tag' );
$tag->name = 'Art Deco';
//creates product_tag table!
$vase->sharedTagList[] = $tag;
$lamp->sharedTagList[] = $tag;
R::storeAll( [$vase, $lamp] );

性能问题

像orm这样的参数通常很慢,消耗更多的内存,并且往往使应用程序变慢。我想他们不是在谈论红豆。

我们已经在MySQL和Postgres上进行了测试,相信我,性能从来都不是瓶颈。

不可否认的是,orm增加了一点开销,并且倾向于使您的应用程序变慢(只是一点点)。使用ORM主要是在开发人员时间和稍慢的运行时性能之间进行权衡。我的策略是首先使用ORM构建端到端应用程序,然后基于测试用例,调整速度关键模块以使用直接数据访问。