【发布时间】:2019-04-29 03:50:48
【问题描述】:
我正在使用postgreSQL,我正在尝试将Elasticsearch 的功能引入我们的系统。我正在使用此算法将数据(每次 1000 行 数据)批量插入 Elasticsearch。问题是它非常缓慢,仅 280 000 行数据就需要大约 15 小时。
据我估计,只需要 26 天 不间断地完成对这个表的索引(有大约 1200 万条记录)。
是否有可能以某种方式优化这种方法并创建一种更快的方法?这就是我目前正在做的事情:
public function run()
{
$es_client = new \Elastica\Client();
$es_index = $es_client->getIndex("vehicle");
$es_type = $es_index->getType("_doc");
$vehicle_ins = new Vehicle;
$step = 1000;
$min_vehicle_id = $vehicle_ins->query()->min('id');
$max_vehicle_id = $vehicle_ins->query()->max('id');
$insert_counter = 1;
$docs = [];
for ($i = $min_vehicle_id ; $i <= $max_vehicle_id ; $i += $step) {
$x = $i;
$y = $i + $step;
$vehicles = $vehicle_ins->query()
->where('id', '>=', $x)
->where('id', '<', $y)
->get();
foreach ($vehicles as $vehicle) {
$docs[] = new \Elastica\Document(
$vehicle->id,
[
// implementing my columns (91 columns)
]);
echo ".";
if ($insert_counter % $step == 0) {
$es_type->addDocuments($docs);
$es_type->getIndex()->refresh();
$docs = [];
echo "\n";
echo $step . " rows inserted!";
echo "\n";
}
$insert_counter++;
}
}
if (!empty($docs)) {
$es_type->addDocuments($docs);
$es_type->getIndex()->refresh();
$docs = [];
}
}
P.S:我使用elastica 与Elasticsearch 一起工作,应用程序位于Laravel 5.7 中,postgreSQL 作为主数据库。
P.S:ElasticSearch website 中也提出了这种方法,但对于我正在处理的数据量来说,它仍然太慢了。
【问题讨论】:
-
每次
addDocument操作后是否需要调用refresh?此外,laravel 有一个内置的chunk方法,可以为你“分页”你的结果,所以不需要那种选择 -
->where('id', '>=', $x)->where('id', '<', $y)如果没有 id 索引可能会很慢,而且肯定会比内部使用limit ... offset的skip($x)->take($step)慢,并且不需要对行数据进行任何实际比较.
标签: php laravel postgresql elasticsearch optimization