Laravel:如何优化多个查询

时间:2017-11-02 06:11:55

标签: php mysql laravel query-optimization laravel-5.3

HomeController文件上的查询会降低网站的速度。页面完全加载需要20秒。 (页面大小仅为3.9 Mb,每次加载页面时CPU负载高达80%)。我被告知使用比Elequant更快的查询生成器并加入查询以将它们作为一个查询发送。我发现这太难了。我在哪里可以看到一些这样的例子?

HomeController

public function index()
{
    $sliders = Post::where('post_type','slider')
        ->with('FeaturedImage','PostField')
        ->orderBy('created_at', 'desc')
        ->limit(4)
        ->get();

    $page1 = Post::where([
        ['post_type','=','custom_page'],
        ['slug','=','page1'],
    ])
        ->with('FeaturedImage','PostField')
        ->latest()
        ->first();


    $page2 = Post::where([
        ['post_type','=','custom_page'],
        ['slug','=','page2'],
    ])
        ->with('FeaturedImage','PostField')
        ->latest()
        ->first();


    $page3 = Post::where([
        ['post_type','=','custom_page'],
        ['slug','=','page-3'],
    ])
        ->with('FeaturedImage','PostField')
        ->latest()
        ->first();


    $compacts = array(
        'sliders',
        'page1',
        'page2',
        'page3',
    );
    return view('site.home')->with(compact($compacts));
}

编辑: 迁移后

public function up()
{
    // Create table for storing roles
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('author_id');
        $table->integer('category_id')->nullable();
        $table->string('title');
        $table->text('excerpt')->nullable();
        $table->text('body')->nullable();
        $table->string('slug')->nullable();//unique()
        $table->string('post_type')->default('post');
        $table->enum('status', ['PUBLISHED', 'DRAFT', 'PENDING'])->default('DRAFT');
        $table->timestamps();
    });
}

2 个答案:

答案 0 :(得分:2)

您对posts表运行了四个查询,但没有一个使用索引。这意味着对posts表进行了四次全表扫描。此外,您还要在非索引字段上进行排序。这也可能导致性能问题。

对于您的查询条件,您需要post_typeslug上的索引。您可以创建两个单独的索引,也可以创建一个复合索引。这取决于您的应用需求。

$table->string('slug')->nullable()->index();
$table->string('post_type')->default('post')->index();

答案 1 :(得分:1)

你可能想做这样的事情来获取所有页面,然后使用集合groupBy()函数分割页面

Post::where('post_type','=','custom_page')
->whereIn('slug',['page1','page2','page-3'])
->whereRaw('id IN (select MAX(id) FROM post GROUP BY slug)')
->with('FeaturedImage','PostField')
->get()
->groupBy('slug');