DDC-1149: Optimize OneToMany and ManyToMany without join #1446

Closed
opened 2026-01-22 13:14:40 +01:00 by admin · 11 comments
Owner

Originally created by @doctrinebot on GitHub (May 12, 2011).

Originally assigned to: @guilhermeblanco on GitHub.

Jira issue originally created by user morfi:

/****
 * @Entity
 * @Table(name="users")
 */
class User {

    /****
     * @Column
     * @Id
     */
    public $user_id;

    /****
     * @Column
     */
    public $email;

    /****
     * @OneToMany(targetEntity="Language", mappedBy="user",fetch="EAGER")
     */
    public $languages;

}

/****
 * @Entity
 * @Table(name="user_languages")
 */
class Language {

    /****
     * @Column
     * @Id
     */
    public $user*language*id;

    /****
     * @ManyToOne(targetEntity="User", inversedBy="languages")
     * @JoinColumn(name="user*id", referencedColumnName="user*id")
     */
    public $user;

    /****
     * @Column
     */
    public $user_id;
}
$users = $em->getRepository('User')->findAll();

Result:

SELECT t0.user*id AS user*id1, t0.email AS email2 FROM users t0
SELECT t0.user*language_id AS user_language_id1, t0.user_id AS user_id2, t0.user_id AS user_id3 FROM user_languages t0 WHERE t0.user*id = ?
array(1) {
  [0]=>
  string(1) "1"
}
array(1) {
  [0]=>
  NULL
}
SELECT t0.user*language_id AS user_language_id1, t0.user_id AS user_id2, t0.user_id AS user_id3 FROM user_languages t0 WHERE t0.user*id = ?
array(1) {
  [0]=>
  string(1) "2"
}
array(1) {
  [0]=>
  NULL
}
SELECT t0.user*language_id AS user_language_id1, t0.user_id AS user_id2, t0.user_id AS user_id3 FROM user_languages t0 WHERE t0.user*id = ?
array(1) {
  [0]=>
  string(1) "3"
}
array(1) {
  [0]=>
  NULL
}

...

Need result:

SELECT t0.user*id AS user*id1, t0.email AS email2 FROM users t0
SELECT u0*.user_language_id AS user_language_id0, u0_.user_id AS user_id1, u0_.user_id AS user_id2 FROM user_languages u0_ WHERE u0_.user*id IN (1, 2, 3)
Originally created by @doctrinebot on GitHub (May 12, 2011). Originally assigned to: @guilhermeblanco on GitHub. Jira issue originally created by user morfi: ``` /**** * @Entity * @Table(name="users") */ class User { /**** * @Column * @Id */ public $user_id; /**** * @Column */ public $email; /**** * @OneToMany(targetEntity="Language", mappedBy="user",fetch="EAGER") */ public $languages; } /**** * @Entity * @Table(name="user_languages") */ class Language { /**** * @Column * @Id */ public $user*language*id; /**** * @ManyToOne(targetEntity="User", inversedBy="languages") * @JoinColumn(name="user*id", referencedColumnName="user*id") */ public $user; /**** * @Column */ public $user_id; } ``` ``` $users = $em->getRepository('User')->findAll(); ``` Result: ``` SELECT t0.user*id AS user*id1, t0.email AS email2 FROM users t0 SELECT t0.user*language_id AS user_language_id1, t0.user_id AS user_id2, t0.user_id AS user_id3 FROM user_languages t0 WHERE t0.user*id = ? array(1) { [0]=> string(1) "1" } array(1) { [0]=> NULL } SELECT t0.user*language_id AS user_language_id1, t0.user_id AS user_id2, t0.user_id AS user_id3 FROM user_languages t0 WHERE t0.user*id = ? array(1) { [0]=> string(1) "2" } array(1) { [0]=> NULL } SELECT t0.user*language_id AS user_language_id1, t0.user_id AS user_id2, t0.user_id AS user_id3 FROM user_languages t0 WHERE t0.user*id = ? array(1) { [0]=> string(1) "3" } array(1) { [0]=> NULL } ... ``` Need result: ``` SELECT t0.user*id AS user*id1, t0.email AS email2 FROM users t0 SELECT u0*.user_language_id AS user_language_id0, u0_.user_id AS user_id1, u0_.user_id AS user_id2 FROM user_languages u0_ WHERE u0_.user*id IN (1, 2, 3) ```
admin added the New Feature label 2026-01-22 13:14:40 +01:00
admin closed this issue 2026-01-22 13:14:40 +01:00
Author
Owner

@doctrinebot commented on GitHub (May 12, 2011):

Comment created by @beberlei:

Sure you are on git master? this should be optimized already with fetch=EAGER

@doctrinebot commented on GitHub (May 12, 2011): Comment created by @beberlei: Sure you are on git master? this should be optimized already with fetch=EAGER
Author
Owner

@doctrinebot commented on GitHub (May 12, 2011):

Comment created by morfi:

Attach test file

I run

git clone git://github.com/doctrine/doctrine2.git
git clone git://github.com/doctrine/common.git
git clone git://github.com/doctrine/dbal.git

and run testDoctrine.php

Result


SELECT t0.user*id AS user*id1 FROM users t0

SELECT t0.post*id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user*id = ?

array(1) {
  [0]=>
  string(1) "1"
}
array(1) {
  [0]=>
  NULL
}
SELECT t0.post*id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user*id = ?

array(1) {
  [0]=>
  string(1) "2"
}
array(1) {
  [0]=>
  NULL
}
SELECT t0.post*id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user*id = ?

array(1) {
  [0]=>
  string(1) "3"
}
array(1) {
  [0]=>
  NULL
}
@doctrinebot commented on GitHub (May 12, 2011): Comment created by morfi: Attach test file I run ``` git clone git://github.com/doctrine/doctrine2.git git clone git://github.com/doctrine/common.git git clone git://github.com/doctrine/dbal.git ``` and run testDoctrine.php Result ``` SELECT t0.user*id AS user*id1 FROM users t0 SELECT t0.post*id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user*id = ? array(1) { [0]=> string(1) "1" } array(1) { [0]=> NULL } SELECT t0.post*id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user*id = ? array(1) { [0]=> string(1) "2" } array(1) { [0]=> NULL } SELECT t0.post*id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user*id = ? array(1) { [0]=> string(1) "3" } array(1) { [0]=> NULL } ```
Author
Owner

@doctrinebot commented on GitHub (Oct 10, 2011):

Comment created by @guilhermeblanco:

Please instead of using fetch="EAGER", please use fetch="EXTRA_LAZY". It would fix your issue.
I have successfully tested this situation in 2.2-DEV and it works like a charm. =)

@doctrinebot commented on GitHub (Oct 10, 2011): Comment created by @guilhermeblanco: Please instead of using fetch="EAGER", please use fetch="EXTRA_LAZY". It would fix your issue. I have successfully tested this situation in 2.2-DEV and it works like a charm. =)
Author
Owner

@doctrinebot commented on GitHub (Mar 25, 2013):

Comment created by fludimir:

Doctrine ORM 2.3.3 (Symfony2.2) - using LAZY or EXTRA_LAZY fetch mode there are only one query for:
$users = $em->getRepository('User')->findAll();

but additional users_count queries for
foreach($users as $user) $user->languages->toArray()

And if use fetch EAGER - for some reason there are 2 x users_count queries , ie each query
SELECT t0.post*id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user*id = ?
with unique user_id executed twice

@doctrinebot commented on GitHub (Mar 25, 2013): Comment created by fludimir: Doctrine ORM 2.3.3 (Symfony2.2) - using LAZY or EXTRA_LAZY fetch mode there are only one query for: `$users = $em->getRepository('User')->findAll();` but additional **users_count** queries for `foreach($users as $user) $user->languages->toArray()` And if use fetch EAGER - for some reason there are **2 x users_count** queries , ie each query `SELECT t0.post*id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user*id = ?` with unique user_id executed twice
Author
Owner

@doctrinebot commented on GitHub (Aug 4, 2013):

Comment created by koc:

Please fix this issue

@doctrinebot commented on GitHub (Aug 4, 2013): Comment created by koc: Please fix this issue
Author
Owner

@doctrinebot commented on GitHub (Nov 14, 2013):

Comment created by madhkrish:

Is this likely to be resolved soon? Or is there a good workaround that we could implement?

@doctrinebot commented on GitHub (Nov 14, 2013): Comment created by madhkrish: Is this likely to be resolved soon? Or is there a good workaround that we could implement?
Author
Owner

@doctrinebot commented on GitHub (Nov 28, 2013):

Comment created by col:

Any news on this issue?

@doctrinebot commented on GitHub (Nov 28, 2013): Comment created by col: Any news on this issue?
Author
Owner

@doctrinebot commented on GitHub (Jan 17, 2014):

Comment created by flip101:

(y) sounds very useful !

@doctrinebot commented on GitHub (Jan 17, 2014): Comment created by flip101: (y) sounds very useful !
Author
Owner

@doctrinebot commented on GitHub (Apr 16, 2014):

Comment created by @guilhermeblanco:

As of b28fa9a05a this issue is fixed

@doctrinebot commented on GitHub (Apr 16, 2014): Comment created by @guilhermeblanco: As of https://github.com/doctrine/doctrine2/commit/b28fa9a05a868d42c9b161cda3c73a8c5822acb4 this issue is fixed
Author
Owner

@doctrinebot commented on GitHub (Apr 16, 2014):

Issue was closed with resolution "Fixed"

@doctrinebot commented on GitHub (Apr 16, 2014): Issue was closed with resolution "Fixed"
Author
Owner

@doctrinebot commented on GitHub (Dec 13, 2015):

Imported 1 attachments from Jira into https://gist.github.com/42476e78f6e5a04da901

@doctrinebot commented on GitHub (Dec 13, 2015): Imported 1 attachments from Jira into https://gist.github.com/42476e78f6e5a04da901 - [10991_testDoctrine.php](https://gist.github.com/42476e78f6e5a04da901#file-10991_testDoctrine-php)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#1446