2016-06-23 3 views
4

私はWebアプリケーションの開発に本当に新しいので、laravelを使って作業していますので、私は本当に簡単な質問を言い訳にします...しかし、誰かが私に答えてくれたら、 ..LaravelのEloquentsとChunkの使用は、何百万というレコードで作業しているときに、laravelの通常のクエリービルダーと比べて遅いですか?

私が最初に私のテーブル構造記述することから始めましょう:レコードの13Kの周りに私が使用していますTable Structure

、MySQLのInnoDBの...そして、現在、このテーブルの店舗をし、何百万またはレコードの十億を保存するために作られています将来的に...

ここで私の問題を説明します:

larkの通常のクエリービルダーを使って、このテーブル(つまり、レコードをフェッチする方法を説明するコード)を使って、このテーブル、つまり13kレコードからすべてのレコードを取得すると、1.39秒以内に結果が得られますが、効率的です(これらの結果は、システム上のRAMが限られているため、ハイエンドシステムではテストしていない可能性があります)。しかし、ここでも間違いを犯している場合はお知らせください。

DB::table($tableName->dataTableName)->orderBy('id')->chunk(100, function($data) { 
    foreach ($data as $record) { 
     echo "DateTime: " .$record->DateTime. " id: ".$record->meter_id; 
    } 
}) 

と私はチャンクを使用して説得力と同じことを行う(コード以下、私は雄弁使用してレコードをフェッチする方法を説明し)、私は完全に受け入れられないとする、さらには60秒後に完全な結果を得ることはありませんが...

私は、テーブル名を取得するために dataモデルで他のモデルを使用して行う
Data::orderBy('id')->chunk(100, function($data) { 
    foreach ($data as $record) { 
     echo "DateTime: " .$record->DateTime. " id: ".$record->meter_id 
    } 
}) 

...続きdataモデルの内容です...

<?php namespace App; 

use Illuminate\Database\Eloquent\Model; 
use App\dataTableMaster as DataTableMaster; 
use App\Company; 

class Data extends Model { 

    /** 
    * The database table used by the model. 
    * 
    * @var string 
    */ 
    protected $table = 'data'; 

//========This following constructor assigns table name depending upon client which has logged in... =============== 
    public function __construct(){ 
     $user = \Auth::user(); 
     $associatedIdOfUser = $user->asso_id; 
     $associatedCompanyObjectOfUser = Company::where('id',$associatedIdOfUser)->first(); 
     $companyRoot = $associatedCompanyObjectOfUser->getRoot(); 
     $tableObject = DataTableMaster::where('company_id',$companyRoot->id)->orderBy('created_at','desc')->first(); 
     $this->table = $tableObject->dataTableName; 
    } 

} 

N OW、私の質問は以下のとおりです。

  1. eloquentsは、結果のオブジェクトを作成し、後で1つのdoesntのは、そう、本当にため、通常のクエリー・ビルダーより遅いeloquentsです??。
  2. そのうち、私は取得していますので、
    1. ミスは、私がここで作っていたものよりクエリビルダのような何千ものレコードまたは数百万をフェッチするために効率的なだけでなくとしてeloquentsははるかに遅いビルダーすなわちeloquentsを照会するために比較されていない場合問題?それはテーブルの構造や方法で、私はレコードを取得しているか、それは何ですか?それらについて説明してください。
    2. 雄弁を使ってこのような大きなテーブルで作業することをお勧めしますか?
    雄弁が本当に遅く、どのような方法よりも何百万ものレコードで作業しているのではない場合は、何百万というテーブルで作業することができます。また、なぜ彼らは遅くなっているのですか?それはオブジェクトを作成するか、理由が何か他のものなのですか?
+0

'data'モデルは他のモデルを含む' protected $ with = [] 'を持っていますか?また、[debugbar](https://github.com/barryvdh/laravel-debugbar)を使用することもできます。これは、Laravelを使用する開発者にとって非常に便利です。 – Ohgodwhy

+0

いいえ、それは保護された$を含んでいません...しかし、私は 'protected $ table = $ tableName'を設定するために他のモデルを使用します – nik

+0

私は問題のデータモデルの内容を追加しました... – nik

答えて

2

Eloquentを使用すると、クエリビルダを直接使用するよりも約3倍遅くなります(benchmarks)。 ORMはオブジェクトにデータをマップする必要があるため、常に遅くなります。

何百万というレコードを扱う予定の場合は、ORMを忘れてください。それはあなたのためにもう存在しません。カスタムクエリを実行する必要があります。

100でチャンクするだけでは不十分です。5000まで増やしても安全だと分かっています。メモリ使用量を監視することで、この数値を増減することができます。

sqlはphpより高速ですので、sqlでできるだけ多くのことを行うようにしてください。必要なフィールドだけを選択することを忘れないでください。メモリ使用量が減少します。

大規模なデータセットでは、メモリではなくファイルシステムでソートが行われるため、順序が遅くなります。

DB::table('data')->select('DateTime', 'meter_id')->chunk(5000, function($data) { 
    foreach ($data as $record) { 
     echo "DateTime: " .$record->DateTime. " id: ".$record->meter_id; 
    } 
}); 

設定によっては、エコーが多くのものを遅くすることがあります。

関連する問題