laravel-mongodb查询性能调优:执行计划分析

laravel-mongodb查询性能调优:执行计划分析

【免费下载链接】laravel-mongodb A MongoDB based Eloquent model and Query builder for Laravel (Moloquent) 【免费下载链接】laravel-mongodb 项目地址: https://gitcode.com/gh_mirrors/la/laravel-mongodb

在使用laravel-mongodb开发应用时,随着数据量增长,查询性能可能成为瓶颈。执行计划(Execution Plan)是MongoDB查询优化的核心工具,它能清晰展示查询的执行路径、索引使用情况和耗时分布。本文将通过实例讲解如何利用执行计划分析并优化laravel-mongodb查询性能。

执行计划基础

执行计划是MongoDB查询优化器生成的查询执行方案,包含扫描类型(全表扫描/索引扫描)、索引使用情况、文档匹配数等关键指标。在laravel-mongodb中,可通过explain()方法获取执行计划,该方法位于查询构建器类src/Query/Builder.php中。

执行计划主要关注以下字段:

  • executionStats.executionTimeMillis:总执行时间(毫秒)
  • executionStats.totalDocsExamined:扫描文档数(越小越好)
  • executionStats.totalKeysExamined:扫描索引键数(越小越好)
  • executionStats.nReturned:返回结果数
  • winningPlan.stage:执行阶段(常见有COLLSCAN全表扫描和IXSCAN索引扫描)

获取执行计划的两种方式

1. 链式调用explain()方法

在查询构建器中直接调用explain()方法,返回原始执行计划数据:

$plan = Movie::where('year', '>', 2010)
    ->where('rating', '>', 8.5)
    ->orderBy('rating', 'desc')
    ->explain();

// 输出关键指标
echo "执行时间: " . $plan['executionStats']['executionTimeMillis'] . "ms\n";
echo "扫描文档数: " . $plan['executionStats']['totalDocsExamined'] . "\n";
echo "使用索引: " . ($plan['winningPlan']['stage'] === 'IXSCAN' ? '是' : '否');

2. 单元测试中的执行计划验证

在测试文件tests/Query/BuilderTest.php中,可通过断言验证执行计划是否符合预期:

public function testExplainWithIndex()
{
    $plan = Movie::where('title', 'Carrie')
        ->where('year', 1976)
        ->explain();
    
    $this->assertEquals('IXSCAN', $plan['winningPlan']['stage']);
    $this->assertLessThan(100, $plan['executionStats']['executionTimeMillis']);
}

常见性能问题及优化案例

问题1:全表扫描(COLLSCAN)

winningPlan.stage显示为COLLSCAN时,表示查询未使用索引,需扫描全表。

优化前执行计划片段

{
  "winningPlan": {
    "stage": "COLLSCAN",
    "filter": { "year": { "$gt": 2010 } }
  },
  "executionStats": {
    "executionTimeMillis": 520,
    "totalDocsExamined": 15000,
    "nReturned": 120
  }
}

优化方案:创建复合索引

// 迁移文件中添加索引 [database/migrations/XXXX_XX_XX_XXXXXX_create_movies_table.php]
Schema::create('movies', function ($collection) {
    $collection->index(['year' => 1, 'rating' => -1]);
});

优化后执行计划变化

  • stage变为IXSCAN
  • executionTimeMillis降至30ms以下
  • totalDocsExamined等于nReturned

问题2:低效索引排序

executionStats.totalKeysExamined远大于nReturned时,可能存在索引排序问题。

优化前查询

$movies = Movie::where('genre', 'action')
    ->orderBy('release_date', 'desc')
    ->take(20)
    ->get();

优化方案:调整索引为排序字段在前

// 优化索引 [database/migrations/XXXX_XX_XX_XXXXXX_create_movies_table.php]
$collection->index(['genre' => 1, 'release_date' => -1]);

索引优化策略

1. 索引选择性原则

选择区分度高的字段创建索引。例如用户表中email字段选择性高于status字段:

// 高选择性索引(推荐)
$collection->index(['email' => 1]);

// 低选择性索引(谨慎使用)
$collection->index(['status' => 1]); // 仅适用于频繁过滤状态的查询

2. 复合索引顺序

遵循" equality -> sort -> range "原则排列复合索引字段顺序:

// 正确顺序:等值查询字段 -> 排序字段 -> 范围字段
$collection->index([
    'category' => 1,   // equality
    'price' => -1,     // sort
    'stock' => 1       // range
]);

高级优化技巧

1. 读取偏好设置

通过设置读取偏好将查询路由到从节点,减轻主节点压力。在docs/fundamentals/read-operations/read-pref.txt中有详细说明:

$movies = Movie::where('title', 'Carrie')
    ->readPreference(ReadPreference::SECONDARY_PREFERRED)
    ->get();

2. 查询日志分析

启用查询日志记录慢查询,定位性能瓶颈。配置方法见docs/fundamentals/read-operations/query-logging.txt

// 启用查询日志
DB::connection()->enableQueryLog();

// 执行查询
$results = Movie::complexQuery()->get();

// 获取并分析日志
$logs = DB::connection()->getQueryLog();
foreach ($logs as $log) {
    if ($log['time'] > 100) { // 记录慢查询(>100ms)
        Log::warning('Slow query', $log);
    }
}

性能调优工作流

建议遵循以下步骤进行系统调优:

mermaid

总结

执行计划分析是laravel-mongodb性能调优的核心方法。通过关注executionStatswinningPlan字段,可精准定位全表扫描、低效索引等问题。结合索引优化策略和查询调整技巧,多数查询性能可提升10-100倍。建议定期使用查询日志和执行计划对关键业务查询进行审计,建立性能基准并持续优化。

官方文档中还有更多高级优化技巧,可参考:

【免费下载链接】laravel-mongodb A MongoDB based Eloquent model and Query builder for Laravel (Moloquent) 【免费下载链接】laravel-mongodb 项目地址: https://gitcode.com/gh_mirrors/la/laravel-mongodb

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值