2013-12-16 81 views
0

這個問題更新了一個更簡單的解釋。Mongoid to Mongo查詢翻譯

對於我的數據,以下Mongo CLI查詢需要208ms。該查詢檢索18個請求對象的所有數據。

db.videos.find({avg_rating:{$ gt:1},poster_large_thumb:{$ exists:true},release_date:{$ lte:ISODate(「2000-12-31」)}})。sort ({RELEASE_DATE:-1,AVG_RATING:-1,標題:1})。跳躍(30).limit(18).pretty()解釋()

{ 
    "cursor" : "BasicCursor", 
    "nscanned" : 76112, 
    "nscannedObjects" : 76112, 
    "n" : 48, 
    "scanAndOrder" : true, 
    "millis" : 208, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 

    } 
} 
與Mongoid

然而,當我做查詢。它會創建一個沒有實際數據的標準對象。我將這個標準傳遞給迭代它來創建JSON數據結構的方法。由於需要數據,因此必須從數據庫中檢索每個對象。以下是返回標準的條件:

@videos = Video.order_by(release_date:-1,avg_rating:-1,title:1).where(:avg_rating.gt => 1,:poster_large_thumb.exists => 1 ,::release_date.lte => start_date).skip(skip * POSTERS_PER_ROW).limit(limit * POSTERS_PER_ROW)

當我迭代@videos時,每個對象都需要240ms才能從DB中檢索出來,這個來自某個調試輸出。

Getting one object: 
2013-12-18 00:43:52 UTC 
2013-12-18 00:43:52 UTC 
0.24489331245422363 

假設,如果我得到了在Video.order_by所有數據(...)查詢,將採取208ms總I怎麼能強迫它做檢索在一個查詢,而不是單獨獲取每個對象的?

這裏的一些東西導致整個檢索比Mongo CLI要多兩個數量級。

+0

您的mongod日誌將記錄每個需要超過100毫秒的查詢 - 您可以在那裏看到它們的樣子。 –

回答

0

感謝您的想法,我認爲@Arthur提供了重要提示。沒有人能夠回答,因爲它看起來像是另一個代碼 - 我如何訪問標準。

給出的以下查詢,其產生的標準:

@videos = Video.order_by(release_date: 1, avg_rating: 1, title: -1).where(:release_date.ne => 0,:avg_rating.gt => 1, :poster_large_thumb.exists => 1, :release_date.gt => start_date).skip(skip*POSTERS_PER_ROW).limit(limit*POSTERS_PER_ROW).only(:_id, :poster_large_thumb, :title) 

在幾個嵌套的塊我正在與這樣的代碼行斂值:

video_full = @videos[((row_index)*POSTERS_PER_ROW)+column_index] 

此隨機存取表示法似乎是問題所在。它似乎對每個單獨的對象執行完整的Moped查詢,所以POSTERS_PER_ROW * num_rows次。

如果我用這段代碼的循環之前的所有視頻抓取:

video_full = videos_full[((row_index)*POSTERS_PER_ROW)+column_index] 

我只得到:

@videos.each do |video| 
    videos_full.push video 
end 

然後從陣列中,而不是像這樣的標準搶值一個248ms的Moped查詢,所有的對象都用這個查詢來檢索。這是一個巨大的加速。查詢時間從num_rows * POSTERS_PER_ROW * 248ms到248ms

這是我學到的一個重要教訓,所以如果有人可以指向描述這種效應的文檔以及遵循的規則,我一定會很感激。

1

迴應:

  1. 跳過()限制()查詢,往往會得到越來越慢於MongoDB的一面。當跳過遍歷文檔時,更多信息請參閱這裏https://stackoverflow.com/a/7228190/534150

  2. 多個相同的查詢看起來像我一個N + 1類型的問題。這意味着,可能在你看來的某個地方,你有一個循環調用一個懶加載的屬性,所以它一遍又一遍地發送查詢。這些問題通常很難找到,但要跟蹤它們,您需要獲得端到端跟蹤,因爲您可以訪問源代碼,因此您可能是唯一可以這樣做的端點跟蹤。

  3. Mongoid方面看起來對我很正確。

+0

是的,我做了一些實驗,使跳數非常大,例如CLI中的3000,這確實增加了查詢時間,但它仍然只有5毫秒。當我拿出Mongoid作用域並使用一個簡單的查詢條件時,我得到一個簡單的Moped查詢,跳過30時需要195ms。 – pferrel

+0

您似乎是正確的。我迭代集合來構建JSON並一次檢索一個對象。有沒有辦法讓他們全部跳過/限制,執行速度要快得多? – pferrel