【发布时间】:2010-11-18 17:17:52
【问题描述】:
我的环境的简短描述:
- Symfony : 1.4.8
- 教义:1.2.3
- Centos 5.5 (PHP 5.3.3)
- MySQL 5.1.52
我在 Symfony 中构建了一个新项目,这是项目架构:
# Car
RjCar:
actAs: { Timestampable: ~ }
columns:
id: { type: integer(4), unsigned: true, primary: true, autoincrement: true }
year: { type: integer(2), unsigned: true, notnull: true }
engine_mod: { type: string(1000) }
exterior_mod: { type: string(1000) }
suspension_mod: { type: string(1000) }
audio_mod: { type: string(1000) }
vote_pos: { type: integer(4), notnull: true, unsigned: true, default: 0 }
vote_neg: { type: integer(4), notnull: true, unsigned: true, default: 0 }
views: { type: integer(4), notnull: true, unsigned: true, default: 0 }
# Foreign keys
category_id: { type: integer(1), unsigned: true, notnull: true }
category_check: { type: boolean, notnull: true, default: 0 }
user_id: { type: integer(5) }
relations:
RjCategory: { onDelete: CASCADE, local: category_id, foreign: id, foreignAlias: RjCars }
sfGuardUser: { onDelete: CASCADE, local: user_id, foreign: id, foreignAlias: RjCars }
# Category
RjCategory:
columns:
id: { type: integer(1), unsigned: true, primary: true, autoincrement: true }
name: { type: string(255), notnull: true}
# I do not include the sfGuardUser schema, but it's the default one from the plugin
当我想用类别名称和用户名检索最后 10 辆汽车时,我在 RjCarTable.class.php 中使用以下代码:
$last_cars = $this->createQuery('car')
->leftJoin('car.sfGuardUser user')
->leftJoin('car.RjCategory categ')
->orderBy('car.created_at DESC')
->limit(10)
->execute();
return $last_cars;
在我的页面上一切看起来都很好,我得到了所有结果,但在调试栏中,我看到了 22 个查询(而不是应该的 2 个)。
这是第一个正常的查询输出:
SELECT
/* Everything about the car */
r.id AS r__id,
r.year AS r__year,
r.engine_mod AS r__engine_mod,
r.exterior_mod AS r__exterior_mod,
r.suspension_mod AS r__suspension_mod,
r.audio_mod AS r__audio_mod,
r.vote_pos AS r__vote_pos,
r.vote_neg AS r__vote_neg,
r.views AS r__views,
r.type_id AS r__type_id,
r.category_id AS r__category_id,
r.category_check AS r__category_check,
r.user_id AS r__user_id,
r.created_at AS r__created_at,
r.updated_at AS r__updated_at,
/* ... hidden because irrelevant... retrieve everything about the sfGuardUser and profile... */
/* Everything about the category */
r2.id AS r2__id,
r2.name AS r2__name,
FROM rj_car r
LEFT JOIN sf_guard_user s ON r.user_id = s.id
LEFT JOIN rj_category r2 ON r.category_id = r2.id
ORDER BY r.created_at DESC
LIMIT 10
所以在那之前一切正常,除了这个查询后面跟着 20 个其他查询来检索有关每个类别的信息(显然每个结果有 2 个查询),而您可以在前面的查询中注意到这些信息是可用的。我不会把它们都放在这里,但这里有一些:
SELECT r.id AS r__id, r.name AS r__name FROM rj_category r WHERE (r.id = '8') LIMIT 1
SELECT r.id AS r__id, r.name AS r__name FROM rj_category r WHERE (r.id = '8') LIMIT 1
SELECT r.id AS r__id, r.name AS r__name FROM rj_category r WHERE (r.id = '9') LIMIT 1
SELECT r.id AS r__id, r.name AS r__name FROM rj_category r WHERE (r.id = '9') LIMIT 1
/* etc.. 20 times */
所以我真正的问题是: - 为什么它执行所有这些不必要的查询,而第一个查询应该有这些信息? - 为什么 sfGuardUser 表没有发生这种情况?我的 RjCar 对象和 sfGuardUser 对象之间的关系显然与 RjCar 和 RjCategory 之间的关系相同。
如果有人已经面临同样的问题,我会很高兴听到它。正如我所说的一切正常,但我更喜欢这个模块不要生成不必要的查询,因为它应该在我的应用程序的主页上执行。
【问题讨论】:
标签: symfony1 doctrine left-join