为什么关系中的十进制列的搜索(wherehas)在laravel中需要这么长时间?

问题描述 投票:2回答:2

我有一个列表,我从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);
}

实际上,我可以使用原始查询和连接,但因为我使用链查询和分页我不能这样做。

有什么建议可以让这个过程更快吗?

php mysql laravel eloquent
2个回答
3
投票

根据评论,生成的查询有一个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 = ? )

2
投票

创建另一个迁移和add an indexprice表中的prices列:

$table->index('price');
© www.soinside.com 2019 - 2024. All rights reserved.