Join 嵌套多个连接

Join 嵌套多个连接,join,symfony1,doctrine,Join,Symfony1,Doctrine,我正试图用条令优化symfony应用程序。我偶然发现了以下问题: 在视图中,我使用了$project->getProgress();但是这样做会随着项目的增多而增加查询的数量。所以我尝试用左连接将进度放入projects查询(覆盖findAll方法),但没有成功。查询的数量实际上增加了 public function findAll($hydrationMode = null) { $q = $this->createQuery('p') -

我正试图用条令优化symfony应用程序。我偶然发现了以下问题:

在视图中,我使用了$project->getProgress();但是这样做会随着项目的增多而增加查询的数量。所以我尝试用左连接将进度放入projects查询(覆盖findAll方法),但没有成功。查询的数量实际上增加了

public function findAll($hydrationMode = null)
{
    $q = $this->createQuery('p')
                    ->leftJoin('p.progress pr')
                    ->leftJoin('pr.sfGuardUser u')
                    ->leftJoin('p.raws r')
                    ->leftJoin('p.series');
    return $q->execute(array(), $hydrationMode);
}
这就是我试图用尽可能少的查询量创建的结果:

array() {
  [0]=>
  array() {
    ["id"]=> string(1) "1"
    ...
    ["progress"]=>
    array() {
        array() {
            array() { progress1 }
            array() { progress2 }
            array() { progress3 }
            ....
        }
    }
  }
我查阅了symfony和Doctrine的文档,没有找到我的答案。我也在谷歌上搜索了很长一段时间。(几个月来我一直在寻找解决方案)我希望我已经把我的问题描述得足够好了

schema.yml:

projects:
  actAs:
    Timestampable: ~
  columns:
    user_id: integer(4)
    series_id: bigint
    pages: int
    chapter: string
    translators_id: bigint
    proofreaders_id: bigint
    cleaners_id: bigint
    typesetters_id: bigint
    raws_id: bigint
    hide_project: bool
    complete: bool
  relations:
    sfGuardUser:
      local: user_id
      foreign: id
      onDelete: CASCADE
    series:
      local: series_id
      foreign: id
      type: one
      foreignType: many
      onDelete: CASCADE
    progress:
      local: id
      foreign: projects_id
      onDelete: CASCADE
      type: one
      foreignType: many

projectsProgress:
  actAs: [Timestampable]
  columns:
    projects_id: bigint
    user_id: integer(4)
    job:
      type: enum
      notnull: true
      values: [tl,pr,cl,ts]
    beginpage: int
    endpage: int
    complete: bool
    file: string
    url: clob
  relations:
    sfGuardUser:
      local: user_id
      foreign: id
      onDelete: CASCADE
    projects:
      local: projects_id
      foreign: id
      onDelete: CASCADE
      foreignAlias: progress

您需要修改获取
项目
对象的查询以包含联接。通常,获取
Project
对象的查询应该放在
ProjectTable


如果要修改
Project
的所有查询或查询子集,请查看。

使用水合物模式的问题是,您可能会获取不使用的数据。我真的不知道如何获取所有数据,但假设每个项目都会带来所有必需的数据,至少再添加一个查询

对于复杂查询(和优化),我更喜欢手动查询,并在一个查询中管理所有需要的数据,例如:

$query = "SELECT ... FROM projects p LEFT JOIN progress pr (LEFT JOIN sfGuardUser u (LEFT JOIN...) ON pr.user_id = u.id ) ON p.id = pr.projects_id"

$rs = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchAssoc($query);

是一个包含选定数据的数组。拥有所有数据后,您可以随心所欲地创建一个数组,但请记住,这样您只需执行一次查询(减少数据库负载),但需要添加一些时间机器来解析数组。

如果修改查询,查询量将从17增加到253。进度的子集总是空的。我通过如下方式重写代码,成功地将加载时间减少了100-150毫秒:这是最好的方法还是有更好的方法?我正在阅读代码。我们在谈论多少个项目?因为通过这种方式,您可以将db负载转移到解析负载,并且您可能没有使用所有项目(如果是,请过滤它们)。有时最好多一些查询,少一些解析,但始终取决于有多少数据。例如,您可以执行两个查询:一个带来项目数据(if块),另一个带来进度和raws数据。优化查询的方法是减少联接表。我看过你的密码了。我们正在谈论1到20个开放项目,我需要所有的项目,因为这个页面是一个列表,显示了每个开放项目的进展。(忘记添加where条件以过滤已完成的内容)当前页面的加载时间现在是450毫秒。我将尝试使用您的代码,sql有一些问题需要修复。我将比较这两个函数的加载时间。这两个函数都需要大约38ms才能完成,这比以前快得多。谢谢你知道如何加快观看速度吗?这是唯一能让一切变慢的东西。(无法缓存,因为数据是动态的)很好:)我认为加快视图速度的唯一方法是减少foreach的*、*if等,使其尽可能简单。仅加载将要使用的js并减少图像大小。有很多提高网站速度的最佳实践,只需使用google:)例如check