Laravel datatable taking too much of time to load data

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

This is a fantastic observation, and you are right to investigate why your query time dropped from 59.0 seconds to 5.0 seconds! This change likely stems from a more efficient way of utilizing database indexing, even though the overall structure deals with complex date filtering.

As a developer, I can guide you through the efficiency of this process and suggest best practices for optimizing data retrieval in Laravel applications.


Developer Analysis: Optimizing Eloquent Queries

The performance gain you experienced is a direct result of how your conditional filtering logic interacts with the underlying database indexes on the created_at column. The speedup indicates that the previous method was likely forcing full table scans, whereas the new method allowed the database to use indexes effectively.

1. Understanding the Bottleneck: Date Filtering

The core performance challenge in your code lies within the conditional blocks for $filter_type:

// ... inside the if/elseif block ...
elseif ($filter_type == "weekly") {
    $fromDate = Carbon\Carbon::now()->subDay()->startOfWeek()->toDateString();
    $tillDate = Carbon\Carbon::now()->subDay()->endOfWeek()->toDateString();
    $orders = $orders->whereBetween(DB::raw('date(created_at)'), [$fromDate, $tillDate]);
}
// ... and so on for monthly/yearly using MONTH() or YEAR()

When you use functions like MONTH(created_at) or YEAR(created_at) directly in a WHERE clause (as seen in your monthly and yearly filters), standard B-tree indexes on the created_at column often cannot be used efficiently. This forces the database to perform a full table scan, which is why the original 59-second query was slow.

2. Why the New Code is Faster (The Optimization)

When you switch to methods that allow the database to utilize the index structure more effectively—especially when dealing with range comparisons (whereBetween) or when using functions on indexed columns in a way the query planner understands—performance improves dramatically.

Key Takeaway: For date-based filtering, always aim to compare the indexed column directly rather than applying complex calculations to it unless absolutely necessary.

3. Best Practices for Efficient Data Retrieval (Leveraging Laravel)

To maintain high performance, especially as your orders table grows, here are the best practices you should adopt when dealing with large datasets in Laravel:

A. Ensure Proper Indexing

The single most important step is ensuring that your primary filtering columns are properly indexed. Since you are heavily filtering by time, an index on created_at is essential. You already have foreign key indexes (order_store_id_foreign and order_user_id_foreign), but ensure a dedicated index exists for performance-critical lookups:

-- Ensure this index exists if it doesn't already
ALTER TABLE orders ADD INDEX idx_created_at (created_at);

B. Optimize Date Comparisons (The Gold Standard)

For range searches (custom filter), your use of whereBetween('created_at', [$from, $to]) is the most efficient method, as it directly uses a single index entry point. This should be prioritized whenever possible.

C. Handling Grouping Efficiently

If you frequently need to group by month or year, consider using database-level partitioning or creating virtual/generated columns in your database schema for these values. This allows the database to index the results of those calculations directly, making filtering instantaneous.

For example, instead of calculating MONTH(created_at) every time, you could add a column named order_month and update it on insertion:

// In your migration:
$table->unsignedInteger('order_month');
$table->timestamps();

Then, filtering becomes an index lookup: ->where('order_month', $month_value). This shifts the computational load from runtime query execution to write time, offering massive read speedups.

D. Streamlining Data Selection (Projection)

Your code selects many columns for Datatables formatting. While this isn't a speed killer in this specific case, always adhere to the principle of "Select Only What You Need." If you only need to display names and totals, avoid selecting large text fields unless they are explicitly required for the view.

Conclusion

Your performance improvement is a success! It confirms that refining how you ask the database for data—by structuring your WHERE clauses to respect existing indexes—is the key to high-performance development. Continue focusing on leveraging Eloquent's query builder methods (whereBetween, etc.) and consider schema changes (like generated columns) when dealing with complex, repetitive date aggregations. For deeper insights into building performant applications, exploring advanced concepts found on platforms like Laravel is highly recommended.