2016-07-14 77 views
1

這個問題讓我瘋狂。我有一個集合:MongoDB查詢比gte更快lte

var ethTransactionSchema = new mongoose.Schema({ 
    blockNumber: Number, 
    blockHash: String, 
    hash: String, 
    transactionIndex: Number, 
    from: String, 
    to: String, 
    value: String 
}); 
ethTransactionSchema.index({ hash: 1 }, { unique: true }); 
ethTransactionSchema.index({ from: 1 }); 
ethTransactionSchema.index({ to: 1 }); 
ethTransactionSchema.index({ blockNumber: 1, transactionIndex: 1 }); 

ethTransactionSchema.index({ from: 1, to: 1, blockNumber: 1, transactionIndex: 1 }); 
ethTransactionSchema.index({ from: 1, blockNumber: 1, transactionIndex: 1}); 

ethTransactionSchema.index({ to: 1, blockNumber: 1, transactionIndex: 1 }); 
ethTransactionSchema.index({ to: 1, blockNumber: 1 }); 

ethTransactionSchema.index({ from: 1, blockNumber: 1 }); 
ethTransactionSchema.index({ from: 1, to: 1, blockNumber: 1 }); 
ethTransactionSchema.index({ blockNumber: 1 }); 
ethTransactionSchema.index({ transactionIndex: 1 }); 

ethTransactionSchema.index({ blockNumber: -1 }); 
ethTransactionSchema.index({ to: 1, blockNumber: -1 }); 
ethTransactionSchema.index({ from: 1, blockNumber: -1 }); 
ethTransactionSchema.index({ from: 1, to: 1, blockNumber: -1 }); 

ethTransactionSchema.index({ from: 1, to: 1, blockNumber: -1, transactionIndex: -1 }); 
ethTransactionSchema.index({ from: 1, blockNumber: -1, transactionIndex: -1 }); 
ethTransactionSchema.index({ to: 1, blockNumber: -1, transactionIndex: -1 }); 

當我執行此查詢:

find({"$and":[ {"$or": [ {"from":"0x120a270bbc009644e35f0bb6ab13f95b8199c4ad"}, 
         {"to":"0x120a270bbc009644e35f0bb6ab13f95b8199c4ad"} 
        ]}, 
      {"blockNumber":{"$gte":1289597}} 
      ] 
    }).sort({ blockNumber: -1, transactionIndex: -1 }) 

它從3比與LTE相同的查詢6倍以上:

find({"$and":[ {"$or": [ {"from":"0x120a270bbc009644e35f0bb6ab13f95b8199c4ad"}, 
         {"to":"0x120a270bbc009644e35f0bb6ab13f95b8199c4ad"} 
        ]}, 
      {"blockNumber":{"$lte":1289597}} 
      ] 
    }).sort({ blockNumber: -1, transactionIndex: -1 }) 

你可以看到我試過很多索引組合,只是爲了測試我是否可以用frut force來解決這個問題,但我可能會錯過一些東西。出於這個原因,我即將放棄MongoDB。 快速查詢需要56毫秒和慢167毫秒的平均值。

有人能弄清楚有什麼問題或幫我找到它嗎?

回答

4

有一些問題,你正在嘗試做的事:

  1. $or查詢使用索引的不同

    對於$or查詢可以使用索引,所有條款$or查詢必須有一個索引。否則,查詢將是一個集合掃描。這在https://docs.mongodb.com/manual/reference/operator/query/or/#or-clauses-and-indexes

  2. 索引過多收集

    有過多的索引集合中的描述影響性能的方式不止一種,例如,插入性能將受到影響,因爲你正在轉向一個插入操作分成許多部分(即爲集合添加一個插入,爲集合中的每個索引添加一個附加插入)。太多類似索引的索引對查詢規劃器也是有害的,因爲它需要從許多類似索引中選擇一個索引,並且關於哪個索引將更高性能的最少信息。

  3. 入住mongo

    mongo外殼的explain()輸出是發現哪個索引將被查詢中使用的最佳工具的explain()輸出。通常,您希望避免任何COLLSCAN階段(意味着集合掃描)和SORT_KEY_GENERATOR階段(這意味着MongoDB正在使用限制爲32MB的內存中排序,請參閱https://docs.mongodb.com/manual/tutorial/sort-results-with-indexes/)。有關更多詳細信息,請參閱Explain Results

你可能想看看關於索引和查詢性能,這些相關網頁:

話雖如此,我做了快速檢查mongo shell(MongoDB 3。2.8)使用你的例子。你可以嘗試在您的收藏將以下兩個指標:

{blockNumber:1,transactionIndex:1,from:1} 
{blockNumber:1,transactionIndex:1,to:1} 

而且刪除所有其他指標集合英寸這兩個索引應該可以在你的兩個示例查詢中使用。

+0

它對這些指標的工作更糟糕。我認爲問題在於有些查詢返回大量文檔,排序需要時間。我真的不知道如何解釋可以幫助我,它看起來像彙編語言。如果結果是67000,那麼排序很慢。我曾經使用Cassandra,您可以指定表格的默認順序,當您需要以某種順序檢索結果時,該表格的默認順序非常有用。它看起來像蒙戈沒有這個功能,這將是我所需要的。 –