Kurzbeschreibung meiner Umgebung:Lehre: leftJoin auf dem Tisch erzeugt unnötige Abfragen
- Symfony: 1.4.8
- Lehre: 1.2.3
- Centos 5.5 (PHP 5.3.3)
- MySQL 5.1.52
ich habe ein neues Projekt in Symfony gebaut und hier wird das Projekt Schema:
# 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
Wenn ich will die letzten 10 Autos mit Kategorienamen und Benutzernamen, verwende ich den folgenden Code in der RjCarTable.class.php abzurufen:
$last_cars = $this->createQuery('car')
->leftJoin('car.sfGuardUser user')
->leftJoin('car.RjCategory categ')
->orderBy('car.created_at DESC')
->limit(10)
->execute();
return $last_cars;
Auf meiner Seite alles sieht gut aus, ich habe Alle meine Ergebnisse, aber in der Debug-Leiste, sehe ich 22 Abfragen (anstelle von 2, wie es sein sollte). Hier
ist die Ausgabe der Abfrage für die erste, die normal ist:
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
Also, bis dann ist alles normal, außer diese Abfrage durch 20 andere folgen Informationen über die einzelnen Kategorien (2 Abfragen für jede abrufen Ergebnis anscheinend), während Sie in der vorherigen Abfrage feststellen können, dass diese Informationen verfügbar sind. Ich werde nicht alle von ihnen setzen, aber hier einige:
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 */
Also meine wirklichen Fragen sind: - Warum ist es, all diese unnötigen Abfragen durchführen, während die erste Abfrage diese Informationen haben sollte? - Warum passiert das nicht für die Tabelle sfGuardUser? Die Beziehung zwischen meinem RjCar-Objekt und dem sfGuardUser-Objekt ist anscheinend die gleiche wie die zwischen RjCar und RjCategory.
Wenn jemand bereits das gleiche Problem hat, werde ich mich sehr freuen darüber zu hören. Wie ich sage, funktioniert alles gut, aber ich bevorzuge dieses Modul nicht generieren unnötige Abfragen, wie es auf der Homepage meiner Anwendung durchführen sollte.
Während Sie Recht haben, dass es manchmal notwendig ist, aus dem ORM auszubrechen, ist dies definitiv nicht einer der Fälle. –