Estoy jugueteando con MongoDB en PHP construyendo consultas para tratar de hacer las operaciones básicas más rápido. Dejó aquí un codekata para mejorar las operaciones sobre MongoDB, haciendo uso directo del driver de PHP sin librerías.
Insertando 1M documentos en 200 segundos
En un post anterior estuve haciendo los inserts uno a uno. El código fuente se puede ver aquí:
<?php
$mongoManager = new \MongoDB\Driver\Manager('mongodb://127.0.0.1:27017');
//$mongoQuery = new \MongoDB\Driver\Query([]);
$startTime = microtime(true);
for ($i = 0; $i < 1000000; ++$i) {
$insertArray = [
'col1' => md5(uniqid(null, true)),
'col2' => 'Data '.$i,
'col3' => 'Data '.$i,
'col4' => 'Data '.$i,
'col5' => 'Data '.$i,
'col6' => 'Data '.$i,
'col7' => 'Data '.$i,
'col8' => 'Data '.$i,
'col9' => 'Data '.$i,
'col10' => 'Data '.$i,
];
//$insertArray['_id'] = new \MongoDB\BSON\ObjectID();
$bulkWrite = new \MongoDB\Driver\BulkWrite();
$bulkWrite->insert($insertArray);
$mongoManager->executeBulkWrite(
'testing.acollection',
$bulkWrite
);
}
$endTime = microtime(true);
echo 'Taken time: '.($endTime - $startTime).' secs.'.PHP_EOL;
Aquí se hacen 1M de operaciones bulkWrite, que tardan los aproximados 200 segundos.
Ahora insertando 1M documentos en 17 segundos
Dándole una vuelta de tuerca, igual que al usar la librería mongodb/mongodb tenemos una función insertMany, podemos hacer uso directo de estas operaciones de escritura masivas haciendo:
<?php
$mongoManager = new \MongoDB\Driver\Manager('mongodb://127.0.0.1:27017');
//$mongoQuery = new \MongoDB\Driver\Query([]);
$insertArray = [];
$startTime = microtime(true);
$bulkWrite = new \MongoDB\Driver\BulkWrite();
for ($i = 0; $i < 1000000; ++$i) {
$insertArray = [
//'_id' => new \MongoDB\BSON\ObjectID(),
'col1' => md5(uniqid(null, true)),
'col2' => 'Data '.$i,
'col3' => 'Data '.$i,
'col4' => 'Data '.$i,
'col5' => 'Data '.$i,
'col6' => 'Data '.$i,
'col7' => 'Data '.$i,
'col8' => 'Data '.$i,
'col9' => 'Data '.$i,
'col10' => 'Data '.$i,
];
$bulkWrite->insert($insertArray);
if (0 == $i % 1000) {
echo '.';
}
}
$mongoManager->executeBulkWrite('testing.acollection', $bulkWrite);
$endTime = microtime(true);
echo 'done!'.PHP_EOL;
echo 'Taken time: '.($endTime - $startTime).' secs.'.PHP_EOL;
El resultado aquí es el de la imagen del principio, y es que ahora se preparan las 1M inserciones en un sólo bulkWrite, en vez de un bulkWrite por cada inserción. Esto te lo permite también hacer la librería de Composer, lo que no te permitiría es combinar varias de estas operaciones de escritura en un mismo bulkWrite.
Sin embargo, usando directamente la clase \MongoDB\Driver\BulkWrite() sí que se podría juntar en una sóla operación varias operationes de tipo insert, update o delete.