When reviewing code that soon should go live, always hunting for optimisation options, I discovered that a table was queried but the data was not used. In this example it was the user query, but i could not find any user names or email addresses on the generated page.

When digging into the action code I noticed a line like this:

$id = $blog_entry->getUser()->getId();

The id was then used for some other stuff, where actually the id was the only thing that was required from the user table.

Naively examining the line there is nothing wrong with it, however, if you know how propel does handle this internally there is a lot to improve. So we want to have PK of the user.

But BlogEntry and User are joined on the FK user_id. What propel does internally is that it obtains the FK user_id from the table (which is easy, it is stored in there like any other member) and has a reference to an object called aUser which is null.
When now doing the getUser() it notices that aUser is null, takes the user_id does a query and stores this to aUser, which is returned.

Did you notice something? Yes we only want to have the value that we already have! Luckily there is also an accessor for user_id, as it behaves totally the same as any other member.

$id = $blog_entry->getUserId();

Of course you could argue why we access an “internal” join attribute like that, but on the other hand, hey the PK of User could be treated the same way as internal, couldn’t it? And as I was doing this anyway very late in development cycle it is quite unlikely that this will change. And even if it would, getUserId() would fail very similar to getUser()->getId()

Of course this brings only performance where no other data of user is required.
To find similar issues yourself, just do a fulltext search fo “()->getId()” (assuming that you PKs are also called id)