ホームページ > バックエンド開発 > PHPチュートリアル > Laravel Performance Tuning:Scalabilityのためにデータベースクエリを最適化します

Laravel Performance Tuning:Scalabilityのためにデータベースクエリを最適化します

Barbara Streisand
リリース: 2025-01-30 06:04:13
オリジナル
680 人が閲覧しました

Laravel Performance Tuning: Optimizing Database Queries for Scalability Laravelプロジェクトでは、トラフィックが増加するにつれて、データベースが速度を照会することは珍しくありません。最近、不動産プラットフォームのバックエンドを最適化したとき、私はこの問題に遭遇し、そこからいくつかの教訓を学びました。

データベース最適化は、開発可能で高いパフォーマンスアプリケーションの重要な分野の1つです。データの検索速度を改善し、応答時間とページの読み込み時間を短縮し、サーバーの負荷を削減し、コストを最小限に抑えることができます。

不動産プラットフォームの課題

想像:複数の都市にサービスを提供し、高度な検索フィルターを装備した優れた不動産プラットフォームを構築します。不動産リストは速くロードされ、検索フィルターは迅速に応答し、すべてが完璧に見えます。ただし、アプリケーションスケールの拡大とユーザーベースの成長により、開発プロセス中に完全に実行された質問は、より長く機能し始めています。おなじみのように聞こえますか?

これはまさに私たちのプラットフォームが遭遇したものです。 Sentry Alertには、生産環境でデータベースクエリが遅いため、警告が表示されます。監視は、検索結果のクエリが完了するのに5秒以上かかることを示しています - これは私たちが約束する速い経験とはほど遠いものです!

一般的なクエリ欠陥(回避方法)

1。n1お問い合わせ質問:データベースの秘密の敵

ゲームをプレイするとき、1人の敵を倒すことを覚えていますか?複数の小さな敵を生産しますか?これは、LaravelのN 1クエリ問題と本質的に同じです。不動産のリストを取得し、各プロパティに追加の問い合わせを行って、関連データを取得します。気付く前に、データベースは1つだけでなく、何百もの問い合わせを扱っています。

以下は、その典型的な式です:

2。データベースインデックスのアート
<code>// 优化前
$properties = Property::all();
foreach ($properties as $property) {
    echo $property->agent->name;  // 每个房产都会触发一个新的查询
}

// 优化后
// 使用 `with()` 进行预加载
$properties = Property::with(['agent'])->get();
foreach ($properties as $property) {
    echo $property->agent->name;  // 不需要额外的查询!
}</code>
ログイン後にコピー
ログイン後にコピー

データベースインデックスを書き込みのインデックスと比較できます。これらは、各ページをスキャンせずに必要なものを見つけるのに役立ちます。ただし、インデックスは各列に追加されるだけではありません。詳細を探りましょう。

さまざまな種類のインデックスを理解してください

インデックス戦略のベストプラクティス
<code>// 基本的单列索引
Schema::table('properties', function (Blueprint $table) {
    $table->index('price');
});

// 多列的组合索引
Schema::table('properties', function (Blueprint $table) {
    $table->index(['city', 'price']); // 顺序很重要!
});

// 唯一索引
Schema::table('properties', function (Blueprint $table) {
    $table->unique('property_code');
});</code>
ログイン後にコピー
ログイン後にコピー

コンビネーションインデックスの列のシーケンスは重要です
<code>   // 良好:匹配查询模式
   $properties = Property::where('city', 'New York')
                        ->whereBetween('price', [200000, 500000])
                        ->get();

   // 索引应匹配此模式
   $table->index(['city', 'price']); // 首先是城市,然后是价格</code>
ログイン後にコピー
ログイン後にコピー
選択的インデックス
    すべての列がインデックスを必要とするわけではありません。いくつかの列を選択していくつかの列をインデックスするには、次のものが含まれます
  1. columns columsは、句と命令でよく使用されます インデックス外側キー列

      選択性が低い(ブールロゴなど)列をインデックスしないでください
    • 監視インデックスの使用
  2. 3。すべてのコンテンツではなく、必要なコンテンツを選択してください

    私が今まで見た中で最も一般的なエラーの1つは、デフォルトでselect *を使用することです。これは食料品店に行くようなものですが、店全体から物を買うので、食事の材料だけが必要です。以下はより良い方法です:

    <code>// 优化前
    $properties = Property::all();
    foreach ($properties as $property) {
        echo $property->agent->name;  // 每个房产都会触发一个新的查询
    }
    
    // 优化后
    // 使用 `with()` 进行预加载
    $properties = Property::with(['agent'])->get();
    foreach ($properties as $property) {
        echo $property->agent->name;  // 不需要额外的查询!
    }</code>
    ログイン後にコピー
    ログイン後にコピー

    4。大規模なデータセットのセグメンテーション

    大規模なデータセットを処理する場合、システムのリソースを圧倒してボトルネックを引き起こす可能性のある単一の操作ですべてのコンテンツを処理します。代わりに、LaravelのChunkメソッドを使用して、記録可能なバッチ処理レコードを管理できます。

    <code>// 基本的单列索引
    Schema::table('properties', function (Blueprint $table) {
        $table->index('price');
    });
    
    // 多列的组合索引
    Schema::table('properties', function (Blueprint $table) {
        $table->index(['city', 'price']); // 顺序很重要!
    });
    
    // 唯一索引
    Schema::table('properties', function (Blueprint $table) {
        $table->unique('property_code');
    });</code>
    ログイン後にコピー
    ログイン後にコピー
    5。効果的かつ効果的なキャッシュ戦略

    キャッシュは、すべてを覚えている良いアシスタントのようなものです。ただし、他のアシスタントと同様に、明確な指示が必要です。

    <code>   // 良好:匹配查询模式
       $properties = Property::where('city', 'New York')
                            ->whereBetween('price', [200000, 500000])
                            ->get();
    
       // 索引应匹配此模式
       $table->index(['city', 'price']); // 首先是城市,然后是价格</code>
    ログイン後にコピー
    ログイン後にコピー
    プロのヒント:すべてをキャッシュしないでください!焦点:

    頻繁にアクセスされるデータ
    • 高コストでデータを計算します
    • 頻繁に変更されないデータ
    • ベストプラクティス

    最初に監視してから、
      を最適化します 時期尚早の最適化のtrapに入らないでください。 Laravelの構築された-inクエリログや望遠鏡などのツールを使用して、実際のボトルネックを識別します。
    1. サイクルの代わりに集まることで考える データベースをクエリするforeachループを作成したことがわかったときはいつでも、一歩後退して、単一のクエリを使用して対処できるかどうかを尋ねてください。
    2. 戦略的に呼び出します すべてをキャッシュする必要があるわけではありません。頻繁にアクセスし、高コストのクエリに注意してください。
    3. インデックスを作成します
    4. 本のディレクトリとしてインデックスと戦う - あなたは物事をすばやく見つけるのに十分な詳細が必要ですが、それほど多くはなく、ディレクトリは本自体よりも長いです。
    5. 避ける必要がある一般的な欠陥
    6. 不必要な関係を「プリロード」しないでください
    サイクルでクエリを実行しないでください(カモフラージュのn 1問題のトラップ)

    すべてをキャッシュしないでください - キャッシュ管理のオーバーヘッドが利点を超える場合があります
    • 大規模なデータセットの非インデックス列にOrderbyを使用する場合、注意してください
    • 条項
    • ではめったに使用されない列のインデックスを作成しないでください
    • 頻繁に更新することは避けてください
    • 結論:これは旅であり、目的地ではありません
    • データベース最適化は、リストから選択できる1回のタスクではありません。それは庭の世話をするようなものです -
    • 最良の結果を得るために定期的なメンテナンスと注意。これらの基本的な知識から始めて、アプリケーションのパフォーマンスを監視することで、あなたの方法が改善され続けます。
    覚えておいてください、目標は、あなたが知っているすべての最適化技術を達成することではないことです。代わりに、コードメンテナンスとパフォーマンスの間の特定のユースケースに適したバランスポイントを見つける必要があります。時には、複雑な最適化戦略を実行するために数時間を費やすよりも、単純なプレロードステートメントが役立つ場合があります。

    Laravelプロジェクトで何が遭遇し、Laravelプロジェクトでどの問題に遭遇しましたか?コメントで議論しましょう!

以上がLaravel Performance Tuning:Scalabilityのためにデータベースクエリを最適化しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート