2012-06-06 25 views
3

我的理解是查詢null查找空字段以及不存在的字段。MongoDB搜索「null」比搜索「不存在」更快?

蒙戈手冊還指出,「$存在甚至沒有與索引非常有效的」

應該空查詢也被認爲是效率低下?

如果你知道你要找的字段存在,但爲空是它更有效地寫:

db.foo.find({ 「Y」:{$類型:10}})

比:

db.foo.find({ 「Y」:空})

假設字段建立索引

編輯:爲了讓的方式有些背景下,這個正在使用這樣的人可以提出更好的方法: 我正在跟蹤發生在文檔上的處理步驟。 我有每個步驟的時間戳,所以我知道它何時發生。 定期進行家務管理並檢查任何尚未發生的任務(即沒有完成的時間戳),以確保沒有錯過任何東西

回答

2

我不能肯定地說哪一個更快,但有thread in the news group有人在$type查詢的性能問題 - 查詢。

設置,拋開,我不會使用$type查詢的原因有三:

  1. 這是難以閱讀和理解。即使是一個普通的MongoDB用戶也可能不知道什麼{type : 10}不在他的頭頂。
  2. 正如您已經指出的那樣,語義是不同的。 $type查詢允許'兩種不同的空',即文檔中字段不存在的地方,以及存在字段但是爲空的文檔。在反序列化時,這可能會變成大多數語言中相同的對象,但$type-查詢將區分它們。
  3. 索引是爲了索引數據而不是元信息。即使查詢優化器能夠映射它,我仍然堅持更直接的解決方案。

我認爲其他業績風險可能是空值的潛在的低選擇性:如果文件中有一半的文檔的一些價值y和有一半空y,查詢爲空的元素會返回大量的文檔和迭代遊標可能會很昂貴。只有在有很多空值的情況下才是如此。

+0

我完全同意類型語法是可怕的,所以我想避免它,如果可能的話。 –

1

我做了一個快速測試在這裏跑了幾個解釋,看看每個查詢長得很像,首先指定一個與類型:

PRIMARY> db.nulltest.find({ "a" : { $type : 10 } }).explain() 
{ 
    "cursor" : "BtreeCursor a_1", 
    "nscanned" : 110011, 
    "nscannedObjects" : 110011, 
    "n" : 110011, 
    "millis" : 121, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 
     "a" : [ 
      [ 
       null, 
       null 
      ] 
     ] 
    } 
} 

然後一個與null作爲標準:

PRIMARY> db.nulltest.find({ "a" : null }).explain() 
{ 
    "cursor" : "BtreeCursor a_1", 
    "nscanned" : 110011, 
    "nscannedObjects" : 110011, 
    "n" : 110011, 
    "millis" : 122, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 
     "a" : [ 
      [ 
       null, 
       null 
      ] 
     ] 
    } 
} 

結果看起來非常相同(1ms不顯着),索引邊界在解釋上是相同的。因此,我懷疑這裏根本沒有什麼區別,所以堅持更可讀的語法是一個好主意