Reputation: 76
I am getting data from products table, i have use paginate in datatable which shows only 50 records first time, and when pager update to 200 rows it takes 12 to 13sec. Here is my Code. Thanks in Advance
$query = Product::query();
$query->with('def_or_last_supplier','units','prouctImages','productType',
'productBrand','productSubCategory',
'supplier_products','productCategory')
->where('status',1)->orderBy('refrence_no', 'DESC');
if($request->default_supplier != '')
{
$supplier_query = $request->default_supplier;
$query = $query->whereIn('id', SupplierProducts::select('product_id')->where('supplier_id',$supplier_query)->pluck('product_id'));
}
if($request->prod_type != '')
{
$query->where('type_id', $request->prod_type)->where('status',1)->orderBy('refrence_no', 'DESC');
}
if($request->prod_category != '')
{
$query->where('category_id', $request->prod_category)->where('status',1)->orderBy('refrence_no', 'DESC');
}
if($request->filter != '')
{
if($request->filter == 'stock')
{
$query = $query->whereIn('id',WarehouseProduct::select('product_id')->where('current_quantity','>',0.005)->pluck('product_id'));
}
elseif($request->filter == 'reorder')
{
$query->where('min_stock','>',0);
}
}
Upvotes: 0
Views: 145
Reputation: 2059
Your query isn't that big but I think maybe result data size is a bit big
so what you can do is:
1: in my experience is to try to select
your relations fields too you can do that like so
Product::with('def_or_last_supplier',
'units:id,created_at,updated_at', // Just add :field_1,field_2,another_field
'prouctImages:id,field_1,field_2'
....
)
2: I suggest you to take advantage of lazy loading
. if it's possible don't eager load all your relations at once load them where it's needed
$products = Product::get()
In blade or somewhere in application
under a special condition I need to access to my relation, I can easily do that by
$products->load('my_relation_name')
3: I see a lot of orderyBy
clauses in your code, what you can do is to index
the fields that are searchable or needs to be ordered. it can be done by adding ->index()
in your migration file
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('refrence_no')->index();
$table->timestamps();
});
}
4: and finally you can always try to cache your queries to prevent unnecessary queries to database, this is how cache works
$products = Cache::remember('cache_name', $how_long_in_seconds, function () {
return Product::get();
});
And finally here is the eloquent way of your query
$query = \Cache::remember(json_encode($request->toArray()), 300, function () use ($request) {
return Product::with('def_or_last_supplier',
'units',
'prouctImages',
'productType',
'productBrand',
'productSubCategory',
'supplier_products',
'productCategory'
)
->where('status', 1)
->orderByDesc('refrence_no')
->when($request->filled('default_supplier'), function (Builder $query) use ($request) {
$productIds = SupplierProducts::select('product_id')->where('supplier_id', $request->input('default_supplier'))->pluck('product_id');
$query->whereIn('id', $productIds);
})->when($request->filled('prod_type'), function (Builder $query) use ($request) {
$query->where('type_id', $request->input('prod_type'))->where('status', 1)->orderByDesc('refrence_no');
})->when($request->filled('prod_category'), function (Builder $query) use ($request) {
$query->where('category_id', $request->input('prod_category'))->where('status', 1)->orderByDesc('refrence_no');
})->when($request->filled('filter'), function (Builder $query) use ($request) {
$query->when('stock' === $request->input('filter'), function (Builder $query) {
$query->whereIn('id', WarehouseProduct::select('product_id')->where('current_quantity', '>', 0.005)->pluck('product_id'));
})->when('reorder' === $request->input('filter'), function (Builder $query) {
$query->where('min_stock', '>', 0);
});
})->get();
});
Upvotes: 1