与 laravel 在处理数百万条记录时使用块的普通查询构建器相比,Laravel 使用块的 Eloquents 是否更慢?
Is Laravel Eloquents along with using chunks are slower compare to laravel's normal query builders with chunks while working with millions of records?
我在开发 Web 应用程序方面真的很陌生,所以使用 laravel 并学习它们,所以我很抱歉我的问题很简单......但是如果有人回答我这些问题,那将非常有帮助帮我了解这些东西...
让我先从描述我的 table 结构开始:
我正在使用 MySql 的 InnoDB...而这个 table 目前存储了大约 13k 条记录,并且将来会存储数百万甚至数十亿条记录...
现在将我的问题描述如下:
当我从这个 table 中获取所有记录时,即 13k 条记录,使用 laravel 的普通查询构建器使用块(以下代码描述了我获取记录的方式),我得到的结果在 1.39 以内秒,这很好,但实际上它应该更有效(这些结果可能是因为我的系统内存有限,我没有在高端系统上测试过),但是,如果我在这里也犯了错误,那么请让我知道。
DB::table($tableName->dataTableName)->orderBy('id')->chunk(100, function($data) {
foreach ($data as $record) {
echo "DateTime: " .$record->DateTime. " id: ".$record->meter_id;
}
})
当我使用块对 eloquent 执行相同操作时(下面的代码描述了我使用 eloquent 获取记录的方式),即使在 60 秒后我也没有得到完整的结果,这是完全不接受table...
Data::orderBy('id')->chunk(100, function($data) {
foreach ($data as $record) {
echo "DateTime: " .$record->DateTime. " id: ".$record->meter_id
}
})
我确实在data
模型中使用了其他模型来获得table名称...以下是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;
}
}
现在,我的问题是:
- 真的 eloquents 比普通查询构建器慢,因为 eloquents 创建结果对象,而后来的对象不这样做。??
- 如果 eloquents 与查询构建器相比并没有慢很多,即 eloquents 也可以像查询构建器一样高效地获取数千或数百万条记录
- 我在这里犯了什么错误,因此我遇到了问题?是在 table 结构中还是在获取记录的方式中,或者它是什么??请解释一下。
- 是否建议使用 eloquents 处理如此大的 table?
- 如果 eloquents 在处理数百万条记录时确实比使用什么方式更慢且不建议使用,我们可以处理数百万条 table,这是唯一可能的方式他们通过查询生成器??而且,为什么它们变慢了,是因为它创建了对象还是其他原因??
使用 Eloquent 比直接使用查询生成器 (benchmarks) 大约慢 3 倍。 ORM 必须将数据映射到对象,因此它总是比较慢,没有办法解决这个问题。
如果您计划处理数百万条记录,请忘掉 ORM。它对你来说不存在了。您必须执行自定义查询。
100 分块是不够的。我发现增加到 5000 是安全的。您可以通过监控内存使用情况来增加或减少这个数字。
请记住 sql 比 php 快,所以在 sql 中尽可能多地做。记住只 select 您需要的字段 - 它会降低内存使用率。
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 会大大降低速度。
我在开发 Web 应用程序方面真的很陌生,所以使用 laravel 并学习它们,所以我很抱歉我的问题很简单......但是如果有人回答我这些问题,那将非常有帮助帮我了解这些东西...
让我先从描述我的 table 结构开始:
我正在使用 MySql 的 InnoDB...而这个 table 目前存储了大约 13k 条记录,并且将来会存储数百万甚至数十亿条记录...
现在将我的问题描述如下:
当我从这个 table 中获取所有记录时,即 13k 条记录,使用 laravel 的普通查询构建器使用块(以下代码描述了我获取记录的方式),我得到的结果在 1.39 以内秒,这很好,但实际上它应该更有效(这些结果可能是因为我的系统内存有限,我没有在高端系统上测试过),但是,如果我在这里也犯了错误,那么请让我知道。
DB::table($tableName->dataTableName)->orderBy('id')->chunk(100, function($data) {
foreach ($data as $record) {
echo "DateTime: " .$record->DateTime. " id: ".$record->meter_id;
}
})
当我使用块对 eloquent 执行相同操作时(下面的代码描述了我使用 eloquent 获取记录的方式),即使在 60 秒后我也没有得到完整的结果,这是完全不接受table...
Data::orderBy('id')->chunk(100, function($data) {
foreach ($data as $record) {
echo "DateTime: " .$record->DateTime. " id: ".$record->meter_id
}
})
我确实在data
模型中使用了其他模型来获得table名称...以下是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;
}
}
现在,我的问题是:
- 真的 eloquents 比普通查询构建器慢,因为 eloquents 创建结果对象,而后来的对象不这样做。??
- 如果 eloquents 与查询构建器相比并没有慢很多,即 eloquents 也可以像查询构建器一样高效地获取数千或数百万条记录
- 我在这里犯了什么错误,因此我遇到了问题?是在 table 结构中还是在获取记录的方式中,或者它是什么??请解释一下。
- 是否建议使用 eloquents 处理如此大的 table?
- 如果 eloquents 在处理数百万条记录时确实比使用什么方式更慢且不建议使用,我们可以处理数百万条 table,这是唯一可能的方式他们通过查询生成器??而且,为什么它们变慢了,是因为它创建了对象还是其他原因??
使用 Eloquent 比直接使用查询生成器 (benchmarks) 大约慢 3 倍。 ORM 必须将数据映射到对象,因此它总是比较慢,没有办法解决这个问题。
如果您计划处理数百万条记录,请忘掉 ORM。它对你来说不存在了。您必须执行自定义查询。
100 分块是不够的。我发现增加到 5000 是安全的。您可以通过监控内存使用情况来增加或减少这个数字。
请记住 sql 比 php 快,所以在 sql 中尽可能多地做。记住只 select 您需要的字段 - 它会降低内存使用率。
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 会大大降低速度。