2013-03-24 30 views
10

將所有文檔包括在內,包括2個字段,開始時間戳和結束時間戳。在每個我的查詢中,我需要獲取選定時間段內的元素。因此開始應該在選定的值之後,並且最終應該在選定的時間戳之前。用於不同字段的範圍查詢的mongodb索引策略

查詢看起來像

db.collection.find({start:{$gt:DateTime(...)}, final:{$lt:DateTime(...)}}) 

那麼針對該方案的最佳索引策略?


順便說一句,這是獲得更好的性能 - 如日期時間或UNIX時間戳來存儲日期,這是長期價值本身

回答

3

您可以使用一個Compound index以創建多個字段的索引。

db.collection.ensureIndex({start: 1, final: 1}) 

使用explain()得到最出你的數據庫

+0

是的,我知道複合索引。在這種情況下,我唯一擔心的是跨單個字段查詢的複合查詢沒有任何優勢。但我不確定。想想一些需要的實驗。 – 2013-03-24 19:55:07

+0

只要單個字段是複合索引中的第一個字段,您就可以去 – baloo 2013-03-24 19:58:39

11

的比較不同的查詢和索引太添加更多一點baloo的答案。

關於時間戳與長期問題。一般來說,MongoDB服務器不會有任何區別。 BSON編碼長度是相同的(64位)。根據驅動程序的編碼,您可能會在客戶端看到不同的性能。例如,在Java端使用10gen驅動程序時,時間戳將被渲染爲Date,比Long重要得多。有drivers,試圖避免這種開銷。

另一個問題是,如果關閉索引第一個字段的範圍,您將看到性能改進。所以,如果你使用的指數baloo建議:

db.collection.ensureIndex({start: 1, final: 1}) 

您的查詢將執行(可能很多)更好,如果您查詢的是:

db.collection.find({start:{$gt:DateTime(...),$lt:DateTime(...)}, 
        final:{$lt:DateTime(...)}}) 

從概念上講,如果你認爲該指標爲AA的樹的封閉範圍限制了樹的兩側而不是一側。如果沒有封閉範圍,服務器必須「檢查」所有條目,並且所提供的時間戳大於start,因爲它不知道startfinal之間的關係。

你甚至可能會發現查詢性能沒有更好的使用單場指數,如:

db.collection.ensureIndex({start: 1}) 

大部分的儲蓄從第一場的修剪。在這種情況下,情況並非如此,當查詢被索引覆蓋或者可以從索引導出結果的排序/排序時。

HTH - Rob。

+0

關於第一個元素的上限的重大通知。這很自然,可能會影響性能。 =)但仍然猶豫在單場和複合指數之間。想想一些需要的實驗。 – 2013-03-24 19:56:49