【问题标题】:laravel eager loading to minimize querieslaravel 急切加载以最小化查询
【发布时间】:2014-09-18 09:36:51
【问题描述】:

我正在使用带有 DDD 模式的 laravel,这是我为网站制作一些分析报告的代码...

我来自存储库的代码...

//Abstract Entity
  public function getFirstBy($key, $value, array $with = array())
  {
    return $this->repository->getFirstBy($key, $value, $with);
  }


//Link Entity
$link = parent::getFirstBy('hash', $data['hash'], ['visits']);


//prepare report
          $report = [];

          //get dates difference
          $date1 = new \DateTime($data['from']);
          $date2 = new \DateTime($data['to']);
          $date_diff = $date2->diff($date1)->format("%a");

          $time_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->groupBy('created_at')->orderBy('created_at', 'ASC')->get();

          //Total Visits
          $report['total_visits'] = $time_visits->count();

    //country visits
          $country_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->orderBy('country_iso', 'ASC')->groupBy('country_iso')->get();

    //referrers
          $referer_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->where('source', '!=', '')->orderBy('source', 'ASC')->groupBy('source')->get();

    //browsers
          $browser_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->where('browser', '!=', '')->orderBy('browser', 'ASC')->groupBy('browser')->get();

    //os
          $os_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->where('os', '!=', '')->orderBy('os', 'ASC')->groupBy('os')->get();


The code is working perfectly fine but executing 6 mysql queries which could be a big problem for larger usage... 

**sql queries dump...**

    select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' group by `created_at` order by `created_at` asc

    select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' group by `country_iso` order by `country_iso` asc

    select count(*) as total_visits, medium from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' group by `medium` order by `medium` asc

    select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' and `source` != '' group by `source` order by `source` asc

    select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' and `browser` != '' group by `browser` order by `browser` asc

    select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' and `os` != '' group by `os` order by `os` asc

Please suggest some good ways to optimize it better. thanks, i really need advanced help with this.

【问题讨论】:

  • 我们需要更多信息。例如,什么是链接?你如何称呼你的存储库?有关您的业务模式的更多数据。
  • $link 是数据模型。
  • 当然是数据模型,但是如果您希望我们帮助您,那么我们需要对您的模型进行深入了解。很可能您在这里遇到问题是因为建模不好,而 DDD 就是建模。
  • @RafałŁużyński 好的,我会添加更多代码......谢谢
  • @RafałŁużyński 代码已更新,如果您需要查看更多内容,请告诉我。

标签: php mysql laravel laravel-4 domain-driven-design


【解决方案1】:

你可以在ex的关系中使用子查询。

假设 $link 是你的模型对象

$link->with(['Visits'=>function($q){
       $q->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1,$date2))->where('browser', '!=', '')->orderBy('browser', 'ASC')->groupBy('browser');
}])->get();

内部查询将相应地过滤您的所有记录,内部查询仅适用于访问模型

我的建议是首先获取所有记录而不进行任何过滤,然后使用 filter() 方法将它们过滤到集合对象中!所以它只会使用 1 个查询来获取所有记录,然后你只使用 filter() 方法重新排列它们

【讨论】:

  • object of collection with filter() 的任何示例,是的,我正在 $link 对象中获取所有行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 2014-06-12
  • 2014-08-13
  • 2021-04-23
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多