PHP& MySQL性能 - 一个大查询与多个小

时间:2017-05-24 15:51:36

标签: php mysql performance

对于MySQL表我使用的是InnoDB引擎,我的表的结构如下所示:

表格用户

 id |  username  |  etc...
----|------------|--------
  1 | bruce      | ...
  2 | clark      | ...
  3 | tony       | ...

表格用户电子邮件

 id |  person_id  |  email
----|-------------|---------
  1 |          1  | bruce@wayne-ent.com
  2 |          1  | ceo@wayne-ent.com
  3 |          2  | clark.k@daily-planet.com

为了从数据库中获取数据,我编写了一个小框架。例如。在__construct($id)上它检查是否有一个具有给定id的人,如果是,则创建相应的模型并仅将字段id保存到数组中。在运行时,如果我需要模型中的另一个字段,它只从数据库中获取值,将其保存到数组并返回它。例如。与字段emails相同,我的代码访问表user-emails并获取相应用户的所有电子邮件。

对于小型模型,这项工作正常,但现在我正在开发另一个项目,我必须立即获取大量数据以获取列表,这需要一些时间。另外我知道许多与MySQL和许多查询的连接对服务器来说非常紧张,所以..

我现在的问题是:我应该在构建模型时一次获取所有数据(使用左连接等)并将字段保存为数组,还是应该使用其他方法?

2 个答案:

答案 0 :(得分:1)

为什么人们坚持将实体和域对象称为“模型”。

除非您的实体非常大,否则我会在您需要时填充整个实体。而且,如果“电子邮件列表”是该实体的一部分,我也会填充它。

正如我所看到的,问题更多地与“如何处理与外键相关的表”有关。

假设您有UsersArticles个表,其中每篇文章都有user_id个外键的特定所有者关联。在这种情况下,在填充Article实体时,我只会检索user_id值而不是提取有关用户的所有信息。

但是在您使用UsersUserEmails的示例中,电子邮件似乎是User实体的一部分,而您通常会通过$user->getEmailList()调用该电子邮件。

<强> TL; DR

在填充User实体时,我会在两个查询中执行此操作:

  1. 从“用户”表中选择您需要的所有内容并应用于User实体
  2. 从UserEmails表中选择所有用户的电子邮件,并将其应用于User实体。
  3. <强> P.S

    您可能希望查看data mapper模式中的“how”部分。

答案 1 :(得分:0)

在我看来,您应该一次性获取所有字段,并以一种使代码更易于阅读/管理的方式划分查询。

当我们谈论一个或两个查询时,除非组合查询(使用JOIN或其他)过于复杂,否则差异通常可以忽略不计。通常一个或两个索引是非常慢的查询的解决方案。

如果我们谈论的是一对数百或数千个查询,那么当连接/传输开销变得更加重要时,减少查询数量就会产生影响。

您的框架似乎受到premature optimization的影响。你是一个超级担心从一行中获取太多字段,但为什么呢?你有成千上万的专栏吗?

查询的耗时部分几乎总是查找,而不是数据的传输。当您一次拉一个字段时,您正在使数据库一遍又一遍地执行“硬”部分。