Eloquent ORM aggregation vs MySql aggregation

邮差的信 提交于 2020-01-05 05:11:12

问题


I'm working on a Laravel 5.2 project and I'm using Eloquent models, but I'm not sure how to approach to aggregation features.

Let's say I have Product and Price models and a hasMany relationship, so a product can have multiple prices.

Now, in my Product model I'd like a function that will give me an average price of the product.

I found 2 ways to get the same result:

1.) Eloquent aggregation

public function avg_price()
{
     return $this->prices()->avg('price');
}

2.) MySql aggregation

public function avg_price()
{    
    return $this->prices()->groupBy('product_id')->first([\DB::raw('AVG(price) AS avg_price')])->avg_price;
}

So, both of them are showing the right result, however, I'm wondering which one is better to use performance wise.

As far as I understand, Eloquent aggregation would make a collection out of all results (prices) and then calculate the average upon it, and MySQL aggregation would simply do the AVG function in MySQL and return a single row as a result.

I'd like to hear another opinion. Thanks in advance.


回答1:


I cannot make dilemma about these two options. I made a little experiment in this case. Table averager has one column 'value'. The table has 2052195 recorded random integers as well.

$adapter = new mysqli('localhost','korisnik','lozinka','test');
$results = [];

for($i = 1; $i <= 10; $i++){
    $start = microtime(true);
    $res = $adapter->query("select avg(value) as avg from averager");
    $res = $res->fetch_object();
    $results['mysql'] = microtime(true)-$start;

    $start = microtime(true);
    $res = $adapter->query("select * from averager");
    $avg = false;
    while($resItem = $res->fetch_object())
        $avg = $avg ? ($avg+$resItem->value)*0.5 : $resItem->value;

    $results['php'] = microtime(true)-$start;

    echo "Test number {$i}\r\n";
    var_dump($results);
}

Results

Test number 1
array(2) {
  'mysql' =>
  double(3.6330089569092)
  'php' =>
  double(15.645164012909)
}
Test number 2
array(2) {
  'mysql' =>
  double(4.0829129219055)
  'php' =>
  double(16.118007183075)
}
Test number 3
array(2) {
  'mysql' =>
  double(3.5810949802399)
  'php' =>
  double(14.581390857697)
}
Test number 4
array(2) {
  'mysql' =>
  double(4.1148250102997)
  'php' =>
  double(15.509108066559)
}
Test number 5
array(2) {
  'mysql' =>
  double(3.9069290161133)
  'php' =>
  double(14.851855993271)
}
Test number 6
array(2) {
  'mysql' =>
  double(3.4348700046539)
  'php' =>
  double(14.505731105804)
}
Test number 7
array(2) {
  'mysql' =>
  double(3.589262008667)
  'php' =>
  double(14.98966383934)
}
Test number 8
array(2) {
  'mysql' =>
  double(3.6161508560181)
  'php' =>
  double(15.630507946014)
}
Test number 9
array(2) {
  'mysql' =>
  double(4.4143221378326)
  'php' =>
  double(15.816854000092)
}
Test number 10
array(2) {
  'mysql' =>
  double(4.1319460868835)
  'php' =>
  double(15.999732017517)
}


来源:https://stackoverflow.com/questions/40852763/eloquent-orm-aggregation-vs-mysql-aggregation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!