2013-12-16 2 views
0

이 질문은보다 간단한 설명과 함께 업데이트됩니다.몽고이에서 몽고로의 질의 번역

내 데이터의 경우 다음 Mongo CLI 쿼리에는 208ms가 걸립니다. 이 쿼리는 18 개의 요청 된 개체에 대한 모든 데이터를 검색합니다.

db.videos.find ({avg_rating : {$ gt : 1}, poster_large_thumb : {$ exists : true}, release_date : {$ lte : ISODate ("2000-12-31")}}) sort ({출시일 : -1, AVG_RATING : -1, 제목 : 1}). (30)으로 제한 할을 (18) .pretty() 건너 뛸 설명() Mongoid와 그러나

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

    } 
} 

를 내가 쿼리를 수행 할 때. 실제 데이터가없는 기준 오브젝트를 작성합니다. 이 기준을 반복하여 JSON 데이터 구조를 만드는 메소드에이 기준을 전달합니다. 데이터가 필요하기 때문에 각 객체는 DB에서 검색되어야합니다. 검색어를 반환하는 기준은 다음과 같습니다.

@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). 제한 (POSTERS_PER_ROW)

@videos를 반복 할 때 각 객체는 DB에서 검색하는 데 240ms 이상 걸립니다.

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

어떻게 개별적으로 각각의 객체를 얻는 대신 한 쿼리에서 검색을 수행하도록 강제 할 수 있습니다 나는 Video.order_by의 모든 데이터를 가지고있는 경우 (...)가 208ms 걸릴 것 쿼리 것을 이것을 합계 가정?

여기 뭔가가 전체 검색을 Mongo CLI보다 몇 배 이상 더 많이받는 원인이됩니다.

+0

당신의 mongod 로그는 100ms보다 오래 걸리는 모든 쿼리를 기록 할 것입니다 - 당신은 그 모습을 볼 수 있습니다. –

답변

0

아이디어에 감사드립니다. @Arthur는 중요한 힌트를주었습니다. 문제가 다른 코드에있는 것처럼 보였으므로 아무도 대답 할 수 없었습니다.

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

이 랜덤 액세스 표기 :이 같은 코드의 라인으로 값을 잡고있어 몇 가지 중첩 된 블록에서

@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) 

하십시오 기준을 만들어 다음 쿼리를 감안할 때

문제가되는 것 같습니다. 그것은 POSTERS_PER_ROW * num_rows 번 그래서 모든 개별 개체에 대한 전체 Moped 쿼리를 실행하는 것 같습니다.

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

난 단지 얻을 :

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

그럼 대신이 같은 기준의 배열의 값을 잡아 : 나는 모든 동영상이 코드 비트 루프 전에 잡아 경우

하나의 Moped 쿼리가 248ms 인 경우 모든 개체가 해당 쿼리로 검색됩니다. 이것은 엄청난 속도입니다. 질의 시간은 num_rows * POSTERS_PER_ROW * 248ms에서 248ms로 바뀝니다.

이것은 나를 위해 배웠던 커다란 교훈입니다. 누군가가이 효과와 규칙을 설명하는 문서를 가리킬 수 있다면 감사히 여길 것입니다.

1

응답 :.

  1. 건너 뛰기() 제한() 쿼리는 MongoDB의 측면에서 느린 속도가 느린 얻을하는 경향이있다. 건너 뛰기가 문서를 탐색 할 때 자세한 내용은 여기를 참조하십시오. https://stackoverflow.com/a/7228190/534150

  2. 다수의 동일한 검색어가 N + 1 유형의 문제처럼 보입니다. 즉,보기에 어딘가에 지연로드 된 속성을 호출하는 루프가 있으므로 쿼리를 반복해서 보내 게됩니다. 이러한 문제는 흔히 발견하기가 까다 롭지 만 추적하기 위해서는 소스 코드에 액세스 할 수있는 유일한 추적자가 필요합니다.

  3. 몽고이 쪽이 나에게 맞는 것 같습니다.

+0

예, CLI에서 3000과 같이 스킵 번호를 매우 크게 만드는 실험을했는데 쿼리 시간이 길어졌지만 여전히 5 밀리 초 밖에 걸리지 않았습니다. 몽고 이드 스코프를 가져 와서 간단한 쿼리 조건을 사용했을 때 30 초 건너 뛰기 위해 195ms 걸리는 단일 Moped 쿼리가 있습니다. – pferrel

+0

당신은 맞을 것 같습니다. 컬렉션을 반복하여 JSON을 빌드하고 한 번에 하나씩 개체를 검색합니다. 훨씬 더 빨리 실행되는 건너 뛰기/제한과 함께 모든 것을 얻을 수있는 방법이 있습니까? – pferrel