2011-04-30 49 views
3

我为一个项目使用Doctrine 2,它会有很高的流量,并且我关心性能。我应该使用SQL限制还是不是性能原因?

有时我需要为“分页”目的加载很多实体。

示例:加载30,000篇发表的文章,我需要对这些结果进行分页。

我想知道从数据库加载如此多的行有多差,我可以使用LIMIT OFFSET sql语句,但是使用Doctrine 2 &分页,实现Paginator适配器的开销会更大(复杂存储库等),我可以使用一个简单的Iterator适配器。

我想用一个好的缓存系统,它不应该是一个问题,但我不太确定。

顺便说一下,你有关于缓存的任何提示?

回答

5

问题是,无论您使用哪种分页解决方案,当您仅在页面上显示10个数据时,它实际上是否会加载30,000条记录,还是仅载入需要的10条记录?

如果它载入所有记录只是为了显示10,那么它是疯了,你会有性能问题。任何实际值得使用的分页解决方案都只会加载必要的记录。另外,缓存并不是为了解决这些类型的问题(即隐藏低效的算法)。编写高效的代码,速度很快,并且缓存将使您的响应速度更快。

最后,在一个典型的应用程序中,为快速缓存分配的空间非常宝贵,所以不要用一堆你不需要的东西填满它。保持紧密,以便您的缓存可以帮助尽可能快地制作尽可能多的应用程序。

+3

+1因为您应该总是试图从数据库中获取所需的信息。如果显示10条记录,则应提取10条记录并使用count()来确定总计。或者如果第11条记录存在,则获取11条只记录下一个按钮的记录。那么你不需要数数。 – Arjan 2011-04-30 22:26:17

2

我以前没有用过Doctrine,但是几乎所有我看过的分页方法绝对是不要加载完整的数据表来做分页。以最基本的方式,您执行两个查询:一个计算记录数(SELECT COUNT(*) ...),另一个查询您需要的实际行数(SELECT * ... LIMIT ...)。 MySQL通过SQL_CALC_FOUND_ROWSFOUND_ROWS提供了很好的简化。

但是,我曾经在一个项目上工作过一次,其中我需要的数据视图涉及几个具有数千万记录的表的一些相当复杂的联接。执行COUNT(*)每次击中8秒。我最终做的分页是采取一个稍微更现实的方法:人们不用真的使用分页。我的意思是,99%的时间不会超过第一页,对吧?第10页的人数很少,所以我改变了我的查询来选择第一个pageSize * 10 + 1记录(在我的情况下为201)。如果找到的记录数是201,那么我只需打印"You are on page 1 of 'lots'"

2

第2条原则使得它比其他情况更加痛苦。这是您为ORM抽象支付的价格。

从数据库中加载成千上万行是不好。将它们全部水合(将它们变成实体)是可怕的坏

幸运的是,在DoctrineExtensions package有一些帮助。 Paginator扩展有助于抓取您需要的记录片段,并仅保存那些实体。它这样做是在三个查询(一般情况下),这是你能为希望最好的:

  1. 计数的匹配记录
  2. 总数获取的id S为当前页面的实体
  3. 获取这些实体。

我已经在很多场合使用了扩展功能,并取得了很好的成功,对于我来说,对于成千上万条记录来说,它的表现非常好。目前尚不清楚它对于大型数据集或高流量场景的扩展程度如何,但这至少是一个开始。

+0

我没有这个适配器,但是我知道DoctrineExtensions,但是,我使用了一个ServiceLayer,它使得这个适配器很难用于这个项目,但是很好的了解它 – JohnT 2011-05-02 21:02:03

相关问题