我有一個包含大約 1020 萬條記錄的集合。我的聚合查詢大約需要 6 秒才能發回一條記錄。如何優化我的聚合查詢。?索引在 token0address、token1address 和時間戳欄位上定義。
以下是我的查詢
{
$match: {
$or: [
{
token0Address: quoteCurrency,
},
{
token1Address: quoteCurrency,
},
],
timestamp: {
$gte: Number(historyDTO.from),
$lte: Number(historyDTO.to),
},
},
},
{
$group: {
_id: idObj,
transactionDate: { $first: '$transactionDate' },
timestamp: { $first: '$timestamp' },
minimum_price: { $min: '$priceInToken0' },
maximum_price: { $max: '$priceInToken0' },
median_price: { $avg: '$priceInToken0' },
open_price: { $first: '$priceInToken0' },
close_price: { $last: '$priceInToken0' },
volume: { $sum: '$priceInToken0' },
},
},
{ $sort: { timestamp: -1 } },
{ $skip: 0 },
{ $limit: Number(historyDTO.countback) },
idObj 看起來像這樣。它也包含其他組合
if (last === 'H') {
idObj = {
day: { $dayOfYear: '$transactionDate' },
hour: {
$subtract: [
{ $hour: '$transactionDate' },
{ $mod: [{ $hour: '$transactionDate' }, parseInt(exceptLast)] },
],
},
};
}
uj5u.com熱心網友回復:
我會提到一些我認為可以提高性能的更改,但總的來說,我會說這是非常優化的,我個人不會花更多時間優化它,除非它是許多行程的組成部分并且運行時的每一毫秒都很重要。
為兩個欄位創建復合索引
token0Address和token1Address,現在 Mongo 正在使用這些索引,但是它需要基于timestamp. 如果您可以將兩個索引都構建為復合索引,{token0Address: 1, timestamp: 1}那么 Mongo 可以$match更快地完成該階段。(顯然取決于給定的范圍和匹配檔案的規模)。idObj如果可能的話,改變你提到的idObj有不同的結構,也許其中一些有可以消除的冗余,由于$mod操作員的動態使用,這里我們真的不能做任何事情,另一種可能性是預處理所需的欄位(對于本例中的示例要保存$hour結果,因此我們停止使用此操作)。最后一個選項更像是一個技巧,但如果您了解資料分布和查詢的啟發式方法,您可能能夠添加更早的限制并處理更少的資料。這通常不是一個現實的選擇,尤其是在您的資料規模較小的情況下。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/405568.html
標籤:
