Comparison
1) Your EntityRepository::findBy()
approach will do this:
- Query the database for the rows matching your criteria. The database will return the complete rows.
- The database result is then transformed (hydrated) into full PHP objects (entities).
2) Your EntityManager::createQueryBuilder()
approach will do this:
- Query the database for the number of rows matching your criteria. The database will return a simple number (actually a string representing a number).
- The database result is then transformed from a string to a PHP integer.
You can safely conclude that option 2 is far more efficient than option 1:
- The database can optimize the query for counting, which might make the query faster (take less time).
- Far less data is returned from the database.
- No entities are hydrated (only a simple string to integer cast).
All in all less processing power and less memory will be used.
Security comment
Never concatenate values into a query! This can make you vulnerable to SQL injection attacks when those values are (derived from) user-input.
Also, Doctrine2 can't make use of prepared statements / parameter binding, which can lead to some performance-loss when the same query is used often (with or without different parameters).
In other words, replace this:
->where('p.id = '.$id)
->andWhere('p.status = 1')
with this:
->where('p.id = :id')
->andWhere('p.status = :status')
->setParameters(array('id' => $id, 'status' => 1))
or:
->where($qb->expr()->andX(
$qb->expr()->eq('p.id', ':id'),
$qb->expr()->eq('p.status', ':status')
)
->setParameters(array('id' => $id, 'status' => 1))
Additionally
For this particular query, there's no need to use the QueryBuilder
, you can use straight DQL in stead:
$dql = 'SELECT COUNT(p) FROM User\Entity\Members p WHERE p.id = :id AND p.status = :status';
$q = $this->getEntityManager()->createQuery($dql);
$q->setParameters(array('id' => $id, 'status' => 1));
$membersCnt = $q->getSingleScalarResult();