2016-06-01 57 views
0

我試圖在mongodb中插入100萬條記錄,需要這麼多時間,而很多 說它可以這麼快速地告訴我請我的代碼有什麼問題 我使用PHP來做到這一點Iam試圖在MongoDB中插入1百萬行(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

「這麼多時間」有多久了?你認爲/期待什麼「如此之快」? –

+0

我預計它可以在2分鐘內完成 –

+1

需要多長時間,您在哪裏得到了2分鐘內完成的預期?你真的相信一個PHP線程可以在2分鐘內處理1000000次插入嗎?您是否有業務需求來處理單個請求中的1000000次插入?您是否嘗試過運行1000個線程,每個插入1000個條目? –

回答

2

使用Batched/Bulk Inserts代替:

<?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); 
} 

在這裏,我們在同一時間(通過$batchSize可調)插入1000條記錄。這需要MongoDB 2.6或更高版本。

2

您可以使用可從MongoDB 2.6及更高版本獲得的Bulk Operations API來利用插入操作。目前PHP驅動程序應該支持這些方法,在這裏特別需要的MongoWriteBatch類插入操作,特別是建立與MongoInsertBatch類的Insert編寫批處理:

<?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)); 
    } 
?> 

在上面,每個文檔在for循環中創建的數據將添加到插入操作中,然後通過.add()方法將其添加到批處理中,並且僅在調用.execute()時才發送到服務器。按照提供的順序,將有序寫入寫入操作發送到服務器,以便進行串行執行。如果寫入失敗,任何剩餘的操作將被中止。

對模塊操作實現的這些操作的「大小」進行了一些管理,應該通常由驅動程序處理,但如果要檢查寫入結果,則應將其保持在可管理的大小。

這裏的關鍵在於,不是等待來自服務器的針對每個更新的寫入響應,而是以「批量」方式發送和響應操作。在執行批量更新時,這裏「開銷」的減少是相當可觀的,因爲與服務器通信時「往返」較少。

+1

我們有同樣的想法! :) – Will

+1

@Will您可以再次說明,在這兩種方法中,驅動程序都使用基礎批量api分批進行插入操作。 – chridam