Skip to content

BulkUpsert

Alexey Lapin edited this page Jan 22, 2023 · 2 revisions

Public API

You can see the public API in the BulkUpsertContract

Benchmarks

Environment

PHP: 8.1.14

MySQL: 8.0.28

Base test

/** @var GenerateEntityCollectionTestFeature $feature */
$feature = $this->app->make(GenerateEntityCollectionTestFeature::class);
/** @var SaveAndFillEntityCollectionTestFeature $saveFeature */
$saveFeature = $this->app->make(SaveAndFillEntityCollectionTestFeature::class);
/** @var BulkUpsert $bulkUpsert */
$bulkUpsert = $this->app
    ->make(BulkUpsert::class)
    ->chunk(100);

$times = [];
$numberOfQueries = [];
for ($i = 0; $i < 100; $i++) {
    // It generates models without saving
    $entities = $feature->handle(MySqlEntityWithAutoIncrement::class, 100);
    // It saves each model and fill in it the new data
    $saveFeature->handle($entities, 50);

    DB::connection('mysql')->enableQueryLog();
    $start = microtime(true);

    $bulkUpsert->upsert(MySqlEntityWithAutoIncrement::class, $entities, ['id']);

    $times[] = microtime(true) - $start;
    $numberOfQueries[] = count(DB::connection('mysql')->getQueryLog());
    DB::connection('mysql')->disableQueryLog();
    DB::connection('mysql')->flushQueryLog();
}

echo 'time:' . PHP_EOL;
echo 'median = ' . round(collect($times)->median(), 4) . PHP_EOL;
echo 'avg = ' . round(collect($times)->avg(), 4) . PHP_EOL;
echo 'min = ' . round(collect($times)->min(), 4) . PHP_EOL;
echo 'max = ' . round(collect($times)->max(), 4) . PHP_EOL;

echo 'number of queries:' . PHP_EOL;
echo 'median = ' . round(collect($numberOfQueries)->median(), 4) . PHP_EOL;
echo 'avg = ' . round(collect($numberOfQueries)->avg(), 4) . PHP_EOL;
echo 'min = ' . round(collect($numberOfQueries)->min(), 4) . PHP_EOL;
echo 'max = ' . round(collect($numberOfQueries)->max(), 4) . PHP_EOL;

Output

time:
median = 0.0949
avg = 0.1001
min = 0.0879
max = 0.2729
number of queries:
median = 5
avg = 5
min = 5
max = 5
Clone this wiki locally