3

私はWebアプリケーションの開発に本当に慣れていないので、laravelを使ってそれらを学んでいるので、本当に簡単な質問で申し訳ありません..

まず、テーブル構造の説明から始めましょう。テーブル構造

私はMySqlのInnoDBを使用しています...そして、このテーブルには現在約13kのレコードが保存されており、将来的には数百万または数十億のレコードを保存するように作られています...

私の問題を次のように説明します。

このテーブルからすべてのレコード、つまり 13k レコードをフェッチすると、laravel の通常のクエリ ビルダーでチャンクを使用すると (次のコードはレコードをフェッチする方法を説明しています)、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::orderBy('id')->chunk(100, function($data) {
    foreach ($data as $record) {
        echo "DateTime: " .$record->DateTime. " id: ".$record->meter_id
    }
})

dataテーブル名を取得するためにモデル内の他のモデルを使用しています...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;
    }

}

さて、私の質問は次のとおりです。

  1. 雄弁家は結果のオブジェクトを作成し、後でそれを行わないため、実際には雄弁家は通常のクエリビルダーよりも遅くなります.??
  2. 雄弁家がクエリビルダーと比較してそれほど遅くない場合、つまり、雄弁家もクエリビルダーTHANのように数千または数百万のレコードを効率的に取得できます
    1. 私はここでどのような間違いを犯していますか? そのために問題が発生していますか? それはテーブル構造ですか、それとも途中ですか、私はレコードをフェッチしていますか、それとも何ですか?? それらについて説明してください。
    2. 雄弁を使ってそのような大きなテーブルで作業することをお勧めしますか?
  3. 雄弁家が本当に遅く、何百万ものレコードを操作しているときに使用することをお勧めできない場合、何百万ものテーブルを操作できますが、クエリビルダーを介してそれらを操作する唯一の方法はありますか?? また、なぜ遅いのか、それはオブジェクトを作成するためなのか、それとも理由が別のものなのか??
4

1 に答える 1

2

Eloquent を使用すると、Query Builder を直接使用するよりも約 3 倍遅くなります(ベンチマーク)。ORM はデータをオブジェクトにマップする必要があるため、常に遅くなり、それを回避する方法はありません。

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

100 ずつチャンクするだけでは不十分です。5000 まで上げても安全であることがわかりました。メモリ使用量を監視することで、この数を増減できます。

sql は php よりも高速であることを覚えておいてください。また、必要なフィールドのみを選択することを忘れないでください。これにより、メモリ使用量が減少します。

Order by はメモリではなくファイルシステムでソートを行う可能性があるため、大規模なデータ セットでは処理が遅くなります。

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

設定によっては、echo によって処理が大幅に遅くなる可能性があります。

于 2016-07-24T11:00:40.580 に答える