大数跨境

如何在 Laravel 应用中将数据库查询优化了 90%

如何在 Laravel 应用中将数据库查询优化了 90% 索引目录
2025-12-22
3
导读:当我接手一个存在性能问题的 Laravel 应用程序时,最大的瓶颈不是代码,而是我们查询数据库的方式。

当我接手一个存在性能
问题的 Laravel 应用程序时,最大的瓶颈不是代码,而是我们查询
数据库的方式。

问题

该应用程序正在加载包含相关数据的用户仪表盘,这些数据包括订单、
客户、产品和定价。每次页面加载都会触发超过 100 次数据库
查询,渲染耗时 3-5 秒。

调查

我使用 Laravel Debugbar 分析了查询语句,发现了一个典型的 N+1
问题。对于每个订单,我们都分别查询了客户数据、
产品详情和价格信息。

解决方案

第一步:预先加载
我没有采用延迟加载的方式,而是实施了策略性预先加载:

// Before: N+1 queries
$orders = Order::all();
foreach ($orders as $order) {
    echo $order->customer->name; // New query each time!
}

// After: Optimized
$orders = Order::with(['customer', 'items.product'])->get();

步骤 2:查询范围
我为常见数据模式创建了可重用的查询范围:

public function scopeWithFullDetails($query) {
    return $query->with([
        'customer.priceList',
        'items.product.category',
        'payments'
    ]);
}

步骤 3:策略性缓存
对于访问频繁、更改很少的数据(例如产品目录),
我添加了 Redis 缓存:

$products = Cache::remember('products.catalog', 3600, function () {
    return Product::with('category')->get();
});

结果

  • 页面加载时间:3-5 秒 → 小于 500 毫秒
  • 数据库查询:每页 100 条以上 → 每页少于 10 条
  • 服务器负载显著降低
  • 更好的用户体验

经验教训

  1. 优化之前一定要先进行性能分析
    ——不要靠猜测来找出瓶颈所在。
  2. 提前加载是好事
    ——但不要过度加载所有内容。
  3. 合理缓存
    ——并非所有数据都需要实时更新。
  4. 以关系为导向思考
    ——围绕数据之间的关联性来设计查询。

性能优化并非魔法——而是系统分析和
深思熟虑的解决方案。


【声明】内容源于网络
0
0
索引目录
索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
内容 444
粉丝 0
索引目录 索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
总阅读1.1k
粉丝0
内容444