2016-06-01 5 views
0

Ich versuche, 1 Million Datensätze in Mongodb einfügen es dauert so viel Zeit, während viele sagt, dass es so schnell tun kann, sagen Sie mir bitte, was ist falsch mit meinem Code ich bin mit pHP, dassIch versuche, 1 Million Zeile in Mongodb (PHP)

$m = new MongoClient(); 
$db = $m->mydb; 
echo "Database mydb selected"; 

$collection = $db->createCollection("mycol"); 
echo "Collection created succsessfully"; 

$collection = $db->mycol; 
echo "Collection selected succsessfully"; 
for ($i=0; $i<1000000; $i++) 
{ 
    $document = array( 
     "title" => "MongoDB".$i, 
     "description" => "database", 
     "likes" => 100, 
     "url" => "http://www.tutorialspoint.com/mongodb/", 
     "by" => "tutorials point" 
    ); 

    $collection->insert($document); 
} 

echo "Document inserted successfully"; 
+0

Wie lange ist 'so viel Zeit' und was glaubst/erwartest du' so schnell' zu sein? –

+0

ich erwarte es kann es in 2 Minuten tun –

+1

Wie lange dauert es, und wo hast du die Erwartung, dass es in 2 Minuten tun könnte? Und glauben Sie wirklich, dass ein einziger PHP-Thread 1000000 Einfügungen in 2 Minuten verarbeiten kann? Haben Sie eine Geschäftsanforderung, 1000000 Einfügungen in einer einzigen Anfrage zu bearbeiten? Haben Sie versucht, 1000 Threads mit jeweils 1000 Einträgen auszuführen? –

Antwort

2

verwenden Batched/Bulk Inserts stattdessen tun:

<?php 
$m = new MongoClient(); 

$db = $m->mydb; 
echo "Database mydb selected"; 
$collection = $db->createCollection("mycol"); 

$db = $m->mydb; 
echo "Database mydb selected"; 
$collection = $db->mycol; 

$batchSize = 1000; 
$documents = array(); 
for ($i=0; $i<1000000; $i++) 
{ 
     $documents[] = array( 
      "title" => "MongoDB".$i, 
      "description" => "database", 
      "likes" => 100, 
      "url" => "http://www.tutorialspoint.com/mongodb/", 
      "by" => "tutorials point" 
    ); 

     // If we've reached `$batchSize` entries, perform the batched insert. 
     if (($i+1) >= $batchSize) 
     { 
      $collection->batchInsert($documents); 
      $documents = array(); 
     } 
} 

// Finish the last batch. 
if (!empty($documents)) 
{ 
     $collection->batchInsert($documents); 
} 

Hier haben wir 1000 Datensätze zu einer Zeit (einstellbar über $batchSize) einsetzen. Dies erfordert MongoDB 2.6 oder höher.

2

Sie können Ihre Einfügeoperationen mithilfe der Bulk Operations API nutzen, die ab MongoDB 2.6 und höher verfügbar ist. Die aktuellen PHP-Treiber sollten diese Methoden unterstützen, wo insbesondere müssen Sie die MongoWriteBatch Klasse für Einfügeoperationen, insbesondere einen Insert-Write Batch mit der Klasse MongoInsertBatch erstellen:

<?php 
    $mc = new MongoClient("localhost"); 
    $collection = $mc->selectCollection("test", "category"); 

    $batch = new MongoInsertBatch($collection); 
    $counter = 0; 

    for($i=0; $i<1000000; $i++) { 

     $document = array( 
      "title" => "MongoDB".$i, 
      "description" => "database", 
      "likes" => 100, 
      "url" => "http://www.tutorialspoint.com/mongodb/", 
      "by", "tutorials point" 
     ); 
     $batch->add($document); 
     $counter++; 

     if ($counter % 1000 === 0) { 
      $ret = $batch->execute(array("w" => 1)); 
      $counter++; 
      $batch = new MongoInsertBatch($collection);   
     } 
    } 

    if ($counter > 0) { 
     $ret = $batch->execute(array("w" => 1)); 
    } 
?> 

Im obigen jedes Dokument erstellt in der for-Schleife wird zu einer Einfügeoperation hinzugefügt, die dann über die Methode .add() zu einem Stapel hinzugefügt wird und nur beim Aufruf von an den Server gesendet wird. Geordnete Schreiboperationen werden in der angegebenen Reihenfolge zur seriellen Ausführung an den Server gesendet. Wenn ein Schreibvorgang fehlschlägt, werden alle verbleibenden Vorgänge abgebrochen.

Es gibt einige Verwaltung der "Größe" dieser Operationen implementiert mit der Modulo-Operation, die in der Regel vom Treiber behandelt werden sollte, aber dies in überschaubaren Größen hält, sollten Sie das Schreibergebnis überprüfen möchten.

Der Schlüssel hier ist, dass, anstatt auf die Schreibantwort vom Server für jedes einzelne Update zu warten, die Operationen gesendet und in "Batches" beantwortet werden. Die Verringerung des "Overheads" bei der Durchführung von Massenaktualisierungen ist beträchtlich, da bei der Kommunikation mit dem Server weniger "Hin und Her" vorhanden ist.

+1

Wir hatten die gleiche Idee! :) – Will

+1

@Will Sie können das sagen, in beiden Methoden verwendet der Treiber die zugrunde liegende Bulk-API, um die Einsätze in Stapeln zu machen. – chridam

Verwandte Themen