2011-05-09 29 views
0

雖然這與PHP無關,但我在以下示例中使用了PHP。這是否會導致MongoDB性能問題(當通過'打斷'遊標在客戶端執行'limit')?

假設這是限制結果的'正常'方法。

$db->users->find()->limit(10); 

這可能是最快的方式,但也有一些限制,在這裏...在下面的例子中,我將篩選出具有保存價值的某一列的前一行的所有行:

$cursor = $db->users->find(); 
$prev = null; 
$results = array(); 
foreach ($cursor as $row) { 
    if ($row['coll'] != $prev['coll']) { 
     $results[] = $row; 
     $prev = $row; 
    } 
} 

但是,您仍然想要將結果限制爲10,當然。所以,你可以使用以下命令:

$cursor = $db->users->find(); 
$prev = null; 
$results = array(); 
foreach ($cursor as $row) { 
    if ($row['coll'] != $prev['coll']) { 
     $results[] = $row; 
     if (count($results) == 10) break; 
     $prev = $row; 
    } 
} 

說明:由於$cursor實際上並沒有從數據庫中加載的結果,break荷蘭國際集團的foreach -loop將limit它只是爲limit(...) - 功能一樣。

可以肯定的是,這是否正如我所說的那樣工作,或者是否有任何我不知道的性能問題?

非常感謝你, 添

回答

1

說明:自$光標並不實際加載從數據庫中的結果,打破了的foreach循環將限制它只是爲限(...)功能呢。

這不是100%爲真。

當您執行foreach時,您基本上正在發出一系列循環遍歷數據的hasNext/getNext

但是,在此圖層下方,驅動程序實際上是請求並接收成批結果。當您執行getNext時,驅動程序將無縫地爲您提供下一批。

您可以控制批量大小。文檔中的詳細信息應該有助於clarify what's happening

在你的第二個例子,如果你到10,然後break有兩個副作用:

  1. 光標保留在服務器上打開(超時10分鐘,一般不會有大的影響)。
  2. 您可能有更多數據緩存在$cursor中。當$cursor超出範圍時,此緩存將消失。

在大多數情況下,這些副作用是「不大問題」。但是如果你在一個單獨的過程中做了很多這樣的處理,你就需要「清理」,以避免遊標懸停。

+0

非常感謝,這非常有幫助!你知道我怎樣才能在PHP中關閉'$ cursor'。例如,只是「不夠」而已? – elslooo 2011-05-10 16:58:46

+0

'unset()'或者只是讓它超出範圍(*將函數初始化* *) – 2011-05-10 18:39:33

+0

好的,非常感謝! – elslooo 2011-05-11 16:56:57

相關問題