[英]Why does a search (wherehas) for decimal column in a relationship take so long in laravel?
我有一个清单,其中我从laravel退回产品,该清单的每一列都有搜索框,为此,我使用的是:
$q = Product::query();
$q->where('account_id', Auth::user()->account_id);
if ($request->code) {
$q->where('code', 'LIKE' , "%{$request->code}%");
}
if ($request->title) {
$q->where('title', 'LIKE' , "%{$request->title}%");
}
if ($request->price){
$q->whereHas('price', function($query) use ($request){
$query->where('price' ,$request->price);
});
}
$products = $q->with('price', 'images')
->orderBy('id','desc')->paginate($limit);
当我不使用价格部分时,就没有问题,而且速度很快,但是当我使用价格时,这需要很长时间。 价格栏为小数。
产品->价格的关系是:
public function price()
{
// hasOne(RelatedModel, foreignKeyOnRelatedModel = product_id, localKey = id)
return $this->hasOne(Price::class);
}
实际上,我可以使用原始查询并加入连接,但是因为我使用链式查询和分页,所以我无法做到这一点。
有什么建议可以使流程更快吗?
根据评论,生成的查询具有LIKE子句。
SELECT * FROM products
WHERE EXISTS ( SELECT * FROM product_prices
WHERE products.id = product_prices.product_id
AND price LIKE ? )
这将不仅将过滤器中使用的值,而且将product_prices表中的所有值都转换为字符串,以计算匹配项。 这意味着不使用索引,因此查询成为全表扫描,这比索引查找要慢。
我假设实际使用的代码已经复制/粘贴了其他代码和标题条款; 因此它也使用了LIKE查询。 但是,这在实际问题中并未显示。
解决方案是改为进行普通的相等比较,从而允许使用现有索引。
SELECT * FROM products
WHERE EXISTS ( SELECT * FROM product_prices
WHERE products.id = product_prices.product_id
AND price = ? )
创建另一个迁移, 并将索引添加到prices
表的price
列中:
$table->index('price');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.