DISABLE ADBLOCK

ADBlock is blocking some content on the site

ADBlock errore

Which is faster and better to use - query db or iterate over array to find sum of elements

StackOverflow https://stackoverflow.com/questions/18181042
 Checked

Question

I'm using Symfony 2.2 and Doctrine. I have entity Product which has a field for price. In my controller I need to get some Products. So I have something like this:

$products = $this->productRepository->findNeededProducts(some criteria for the products);

And then I need to find the sum of prices for all needed products.

Which is better and faster - to do something like this:

$sum = 0;
foreach ($products as $p) {
    $sum += $p->getPrice();
}

or to write a new query method like this:

public function findSumofProcucts(same criteria here)
{
    $q = $this->createQueryBuilder('p')
        ->add('select', 'SUM(p.price)')
        ->where('p.user = :user') //for example  
        ->setParameter('user', $user)
        ->getQuery();

    return $q->getSingleScalarResult();

}

If I write the query, the two queries - for getting needed products and for finding their sum will be almost identical only this with the sum will have ->add('select', 'SUM(p.price)') and will return SingleScalarResult and isn't this duplication? So I can't decide which is better.

I will be very gratefull if you show me what the best practice is. Thank you very much in advance! :)

Solution

Do the second method. Database aggregate queries execute much faster than PHP code for the same purpose. You have to think of the following heads I am assuming you only need the sum, and not the rest of the rows

Execution Time

Your database software is better at aggregate queries than PHP. PHP will have to iterate over each instance once it has received the data to calculate the sum. Its better to do this in the database, if possible, since it is dealing with the data anyways and has optimized functions to do this sort of thing.

Data Transfer

If all you need is the sum, you are sending a number of rows, their column values that you don't really need. For the sum, you transferring just a single number. If the rowset is large, there will be significant overhead in transferring and might as well take longer to transfer the data than calculating the sum

Conditions

->where('p.user = :user') //for example
For a where query, you again need to check in PHP if the condition matches. Additional overhead. If you need to check a foreign key relation such as where p.category in (SELECT category_id FROM user_categories as uc WHERE p.user=uc.user) . This will require you to fetch each user's categories fromt the database iteratively to do the sum. Complicates program logic

Seperation of Concerns

The data responsibility now also lies on PHP when you can completely outsource it to the database

Where this doesn't apply: If you are displaying each row and the sum, its more sensible to calculate the same rather than shoot another query

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow