2016-04-11 45 views
1

私はidではなく文字列であるカスタムフィールドに関連する5つのテーブルを持っています。Laravel 5.2 sum()を使った左結合の最適化

私は照会したいものに関連する各テーブルの量の合計を取得したいと思います。

私はそれを左結合を使って動作させることができますが、結果を出すには少なくとも10秒かかります。

私のクエリに最適化します。

$raohs = Raoh::leftjoin('func','raoh.FFUNCCOD','=','func.FFUNCCOD') 
      ->leftjoin('appd','raoh.FRAOCOD','=','appd.FRAOCOD') 
      ->leftjoin('altd','raoh.FRAOCOD','=','altd.FRAOCOD') 
      ->leftjoin('obrd','raoh.FRAOCOD','=','obrd.FRAOCOD') 
      ->where(function($query) { 
       $search = \Request::get('search'); 
       $query->where('fraodesc', 'like', '%' . $search . '%') 
        ->orWhere('fsourcod', 'like', '%' . $search . '%'); 
      }) 
      ->where('func.FFUNCCOD', 'like', '%' . trim($ffunccod) . '%') 
      ->select(\DB::raw('fraodesc,fsourcod,raoh.ffunccod,raoh.FRAOCOD,func.ffunction,sum(appd.FAMOUNT) AS fapprop, sum(altd.FAMOUNT) AS fallot, sum(obrd.FAMOUNT) AS foblig')) 
      ->orderBy('ffunction') 
      ->groupBy('raoh.FRAOCOD') 
      ->paginate(20); 

答えて

0

私の質問では、すべてのレコードにSUM()というクエリがロードされているようです(遅くなります)。高速化するために、初期化中にすべてのテーブルに一度だけsum()をleftjoinする必要があります。私はどのようにそれをやったのか。

私はちょうど純粋なSQLを使用して、長い時間前に似たような質問があることを覚えています。 MySQL Make it faster,add members count to family table

$raohs = Raoh::leftjoin('func','raoh.FFUNCCOD','=','func.FFUNCCOD') 
      ->leftjoin(\DB::raw('(Select FRAOCOD, sum(FAMOUNT) as FAMOUNT from appd group by FRAOCOD) as appd'),'raoh.FRAOCOD','=','appd.FRAOCOD') 
      ->leftjoin(\DB::raw('(Select FRAOCOD, sum(FAMOUNT) as FAMOUNT from altd group by FRAOCOD) as altd'),'raoh.FRAOCOD','=','altd.FRAOCOD') 
      ->leftjoin(\DB::raw('(Select FRAOCOD, sum(FAMOUNT) as FAMOUNT from obrd group by FRAOCOD) as obrd'),'raoh.FRAOCOD','=','obrd.FRAOCOD') 
      ->where(function($query) { 
       $search = \Request::get('search'); 
       $query->where('fraodesc', 'like', '%' . $search . '%') 
        ->orWhere('fsourcod', 'like', '%' . $search . '%'); 
      }) 
      ->where('func.FFUNCCOD', 'like', '%' . trim($ffunccod) . '%') 
      ->select(\DB::raw('fraodesc,fsourcod,raoh.ffunccod, raoh.FRAOCOD, func.ffunction, appd.FAMOUNT as fapprop, altd.FAMOUNT as fallot, obrd.FAMOUNT as foblig')) 
      ->orderBy('ffunction') 
      ->groupBy('raoh.FRAOCOD') 
      ->paginate(20); 

それはおよそ秒になりました照会

0

あなたはちょうどあなたがこれらのフィールドの値のために十分な長さのインデックスの長さを指定することを確認し、フィールドraoh.FFUNCCODraoh.FRAOCODにインデックスを追加する必要があるように見えます。たとえば、2〜3シンボルしかない場合は3(またはそれ以上)を指定しても問題ありませんが、長い文字列(10+シンボル)で3を指定すると問題になることがあります。特に、結合が正しく動作しなくなる可能性があります。

Laravel's Migrationsを使用してインデックスを追加する場合は、問題ありません。

これらのインデックスを追加するとパフォーマンスが向上するかどうかをお知らせください。この問題は、お客様のLIKE条件のパフォーマンスが低い場合にも発生する可能性があります。