Laravel 查询生成器 orderBy id DESC 在 100k 行上非常慢
Laravel Query Builder orderBy id DESC is very slow on 100k rows
我有一个包含 10 万个产品的数据库,这是我的查询
$products = DB::table('product')
->leftJoin('product_description', 'product_description.product_id', 'product.product_id')
->leftJoin('product_to_category','product_to_category.product_id','product.product_id')
->select(self::$select_fields)
->where('product_description.language', $language)
->groupBy('product.product_id');
if (!empty($filter->keyword)) {
$products->where('product_description.title','LIKE','%'. $filter->keyword .'%');
}
if (!empty($filter->category_id)) {
$products->where('product_to_category.category_id','=',$filter->category_id);
}
if (!empty($filter->range)) {
$range= explode(',',$filter->range);
$products->whereBetween('product.price', [$range[0], (!empty($range[1]))? $range[1] : $range[0]]);
}
return $products->orderBy('product.product_id','DESC')->where('product.status',1)->limit(50);
此查询加载时间为 12.6 秒。如果我删除 ->orderBy('product.product_id','DESC')
,查询将在 0.800 毫秒内运行。
在我的数据库中,我在 product_description.product_id 、 product_to_category.product_id 和 上有索引键product.id 设置为主
我已经看到 orderBY desc 在大型数据库中速度变慢了很多,有没有解决方法,我需要按 DESC 订购它,因为我想上传“最新”,我试过将它设置为“created_at”列,但大致相同
编辑
我在没有Laravel的情况下尝试过,基本上速度差不多,按DESC排序会减慢查询速度,一般有解决办法还是基本上DESC很慢,应该避免使用大型数据库?
您按 product.product_id
分组,我 猜测 select 仅包含来自产品 table。在那种情况下,左连接可以被删除——或者——被一个存在的查询替换。 group by 可以完全删除。联接乘以行并按压缩它们进行分组;删除后查询变得更简单,希望更快:
select foo, bar, baz
from product
where status = ?
and price between ? and ? -- add this where clause if you need to filter on product price
and exists ( -- add this subquery if you need to filter on description language and/or title
select 1
from product_description
where product_description.product_id = product.product_id
and product_description.language = ?
and product_description.title like ?
)
and exists ( -- add this subquery if you need to filter on category id
select 1
from product_to_category
where product_to_category.product_id = product.product_id
and product_to_category.category_id = ?
)
order by product_id desc
limit 50
我想你可以定义 DESC
索引,因为列的默认索引是 ASC
例如:
CREATE INDEX product_index ON product (product_id DESC);
我有一个包含 10 万个产品的数据库,这是我的查询
$products = DB::table('product')
->leftJoin('product_description', 'product_description.product_id', 'product.product_id')
->leftJoin('product_to_category','product_to_category.product_id','product.product_id')
->select(self::$select_fields)
->where('product_description.language', $language)
->groupBy('product.product_id');
if (!empty($filter->keyword)) {
$products->where('product_description.title','LIKE','%'. $filter->keyword .'%');
}
if (!empty($filter->category_id)) {
$products->where('product_to_category.category_id','=',$filter->category_id);
}
if (!empty($filter->range)) {
$range= explode(',',$filter->range);
$products->whereBetween('product.price', [$range[0], (!empty($range[1]))? $range[1] : $range[0]]);
}
return $products->orderBy('product.product_id','DESC')->where('product.status',1)->limit(50);
此查询加载时间为 12.6 秒。如果我删除 ->orderBy('product.product_id','DESC')
,查询将在 0.800 毫秒内运行。
在我的数据库中,我在 product_description.product_id 、 product_to_category.product_id 和 上有索引键product.id 设置为主
我已经看到 orderBY desc 在大型数据库中速度变慢了很多,有没有解决方法,我需要按 DESC 订购它,因为我想上传“最新”,我试过将它设置为“created_at”列,但大致相同
编辑
我在没有Laravel的情况下尝试过,基本上速度差不多,按DESC排序会减慢查询速度,一般有解决办法还是基本上DESC很慢,应该避免使用大型数据库?
您按 product.product_id
分组,我 猜测 select 仅包含来自产品 table。在那种情况下,左连接可以被删除——或者——被一个存在的查询替换。 group by 可以完全删除。联接乘以行并按压缩它们进行分组;删除后查询变得更简单,希望更快:
select foo, bar, baz
from product
where status = ?
and price between ? and ? -- add this where clause if you need to filter on product price
and exists ( -- add this subquery if you need to filter on description language and/or title
select 1
from product_description
where product_description.product_id = product.product_id
and product_description.language = ?
and product_description.title like ?
)
and exists ( -- add this subquery if you need to filter on category id
select 1
from product_to_category
where product_to_category.product_id = product.product_id
and product_to_category.category_id = ?
)
order by product_id desc
limit 50
我想你可以定义 DESC
索引,因为列的默认索引是 ASC
例如:
CREATE INDEX product_index ON product (product_id DESC);