【发布时间】:2020-06-18 23:20:45
【问题描述】:
我有 4 张桌子:
- 广告(id、name、type_id、city_id)
- 类型(id、slug、名称)
- 城市(id、slug、名称)(37000 个条目)
- 状态(id、slug、名称)(120 个条目)
我可以有这样的网址: https://example.com/ad,type,city.html 或像这样: https://example.com/ad,type,state.html
我需要按 slugs 进行搜索广告过滤,我正在这样做以过滤我的广告:
$slugs = explode(',', $slugs);
$ads = Ad::where('is_active', true)->get();
foreach ($slug as slug){
$types = Type::all();
if ($types->contains('slug', $slug)) {
$type = $types->first(function ($value) use ($slug) {
return $value->slug == $slug;
});
$ads = $ads->where('type_id', $type->id);
$cities = City::all();
if ($cities->contains('slug', $slug)) {
$city = $cities->first(function ($value) use ($slug) {
return $city->slug == $slug;
});
$ads = $ads->where('city_id', $city->id);
$states = State::all();
if ($states->contains('slug', $slug)) {
$state = $states->first(function ($value) use ($slug) {
return $state->slug == $slug;
});
$ads = $ads->where('state_id', $state->id);
}
return $ads;
}
这行得通。 但由于我有很多城市,它可能会很慢(在 1 到 2 秒之间)。 我该如何改进呢? 我正在考虑使用像 memcached 这样的缓存来放置城市,但结果并没有太大变化。也许是我建造它的方式谁错了?
【问题讨论】:
-
你没有“正确地”查询城市和州——你得到了所有这些行(37K 是巨大的)并在应用层而不是数据层对其进行过滤。您也在 for 循环中查询,这也是另一个性能问题。用
whereIn查询那些蛞蝓。 -
首先:看看你在每次循环迭代中查询
::all()。将 $types、$cities 和 $states 移到 foreach 之外。 -
您应该将查询委托给数据库,而不是使用集合
-
或者更好的是,创建一个查询。哪里可能派上用场。
-
非常感谢您的建议