【问题标题】:Doctrine triggering too many database queries学说触发过多的数据库查询
【发布时间】:2012-12-18 10:49:05
【问题描述】:

我已经在 Symfony 中解决了几个星期的问题,但一无所获。

事件和播放列表具有一对多的关系。我的 schema.yml 文件的相关部分:

Event:
  actAs:
    Timestampable: ~
  columns:
    date:
      type: date(25)
      default: '0000-00-00'
      notnull: true
    name:
      type: string(60)
      notnull: true
    host_title_id:
      type: integer
    broadcast_format:
      type: enum(7)
      values:
        - Radio
        - Live
        - Podcast
        - Video
      default: Podcast
      notnull: true
    long_description:
      type: string()
      notnull: true
    geography_id:
      type: integer
      default: NULL
    has_been_emailed:
      type: boolean
      default: '0'
      notnull: true
    active:
      type: boolean
      default: '0'
      notnull: true

Playlist:
  actAs:
    Timestampable: ~
  columns:
    show_time: string(40)
    recorded:
      type: boolean
      default: '0'
      notnull: true
    title: string(100)
    event_id: integer
    podcast_id: integer
  relations:
    Event:
      local: event_id
      foreign: id
      foreignAlias: Playlists

下面的代码是没问题的,它会导致对数据库的一次查询:

return Doctrine_Query::create()
            ->from('Playlist P')
            ->leftJoin('P.Event E')
            ->limit(1)->execute();

以下代码不正确,会导致对数据库的六次查询:

return Doctrine_Query::create()
            ->from('Event E')
            ->leftJoin('E.Playlists P')
            ->limit(1)->execute();

更糟糕的是,使用第二个语句,返回的对象在 [Playlists] 部分中没有数据。即它看起来像这样:

sfOutputEscaperArrayDecorator Object
(
    [count:sfOutputEscaperArrayDecorator:private] => 1
    [value:protected] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [date] => 1998-08-01
                    [name] => Showname
                    [host_title_id] => 1
                    [broadcast_format] => Radio
                    [long_description] => This is an episode.
                    [geography_id] => 25
                    [has_been_emailed] => 1
                    [active] => 1
                    [created_at] => 0000-00-00 00:00:00
                    [updated_at] => 0000-00-00 00:00:00
                    [Playlists] => Array
                        (
                        )

                )

        )

    [escapingMethod:protected] => esc_specialchars
)

这两个命令有什么区别?我不明白。

更新:如果我在模式和 DQL 中将名为 Playlists 的关系更改为 TestPlaylists,效果会更好。它仍然比我预期的多触发一个查询,但返回的对象填充了正确的数据。

【问题讨论】:

  • 我在上面的问题中添加了一个编辑,并附有附加信息。控制器并没有做任何真正有趣的事情,它只是调用唯一内容是问题中的教义查询的函数。
  • 这是因为默认情况下学说不获取关系。因此,每次要获取关系时都需要进行新查询。它可以在列表的每一行。如果您使用join 获取关系,则每次获取关系时,学说都不会执行新查询。此问题也可能出现在 admin gen 列表中。解决方案是强制使用查询管理员。如果您需要更多信息,我可以发布适当的答案。
  • 是的,我想我需要更多信息。那我也可以代理你
  • 我对这个问题做了一些重要的修改。我仍然不明白为什么不同的订单会得到不同的结果
  • 我不知道你真正想要实现什么。你为什么问这个?你为什么要尝试这两个查询?我有点迷茫

标签: php doctrine symfony-1.4


【解决方案1】:

您使用的是什么 Symfony 版本?我刚刚在 Symfony 1.4.18 项目中测试了您的模式,当我从 Doctrine 查询中取出限制时,它们都只创建一个对数据库的查询。

如果我将限制保留在那里,第二个 Doctrine 查询会创建一个额外的数据库查询(即在 Event 上选择 distinct)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 2020-03-06
    • 1970-01-01
    • 2016-12-21
    相关资源
    最近更新 更多