Здравствуйте.
Использую Doctrine 2. Встала проблема
Есть такие сущности:
/**
* @Entity
* @Table(name="users")
*/
class User {
/**
* @Column
* @Id
*/
public $user_id;
/**
* @OneToMany(targetEntity="Post", mappedBy="user",fetch="EAGER")
*/
public $posts;
}
/**
* @Entity
* @Table(name="posts")
*/
class Post {
/**
* @Column
* @Id
*/
public $post_id;
/**
* @ManyToOne(targetEntity="User", inversedBy="posts")
* @JoinColumn(name="user_id", referencedColumnName="user_id")
*/
public $user;
}
Если использовать
$users = $em->getRepository('User')->findAll();
ТО получается очень не оптимально, много запросов:
SELECT u0_.user_id AS user_id0 FROM users u0_
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
}
Если использовать DQL
$users = $em
->createQuery('SELECT user,post FROM User user JOIN user.posts post')
->getResult();
Получается тоже не очень оптимально.
SELECT u0_.user_id AS user_id0, p1_.post_id AS post_id1, p1_.user_id AS user_id2 FROM users u0_ INNER JOIN posts p1_ ON u0_.user_id = p1_.user_id
т.к. много дублирующихся данных
user_id0 |
post_id1 |
user_id2 |
1 |
1 |
1 |
1 |
2 |
1 |
2 |
3 |
2 |
2 |
4 |
2 |
2 |
5 |
2 |
Идеальный вариант был бы:
SELECT u0_.user_id AS user_id0, p1_.post_id AS post_id1, p1_.user_id AS user_id2 FROM users u0_
SELECT t0.post_id AS post_id1, t0.user_id AS user_id2 FROM posts t0 WHERE t0.user_id IN (1,2,3)
Но я не понимаю как это правильно сделать, можно сделать это по отдельности вручную, по как потом объеденить коллекции, при это что бы и Doctrine не пыталась загрузить сама колекцию при объеденении.
Можно по идее убрать Doctrine связи и делать вручную, но тогда перестанут работать стандартные вещи типа сохраниение каскадное, сохранение связей, отложенная загрузка при надобности.
Писал в багтрекер,
www.doctrine-project.org/jira/browse/DDC-1149?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel
Написали что вроде как оптимизировали, но что где и как это работает, не понятно.