2014-11-18 2 views
3

Mongoid 쿼리와 관련된 성능 문제가 발생했습니다. 필자의 초기 임에도 불구하고 (가장 작은 Linode 인스턴스에 있었던) 호스팅과 관련이 있었지만 더 큰 인스턴스로 마이그레이션했을 때 쿼리 속도가 약간 향상되었습니다. 비교를 위해, 제품 페이지는 800ms-1000ms의 속도로 생산에 투입되고 (개발 중 60ms), 호스팅 이전 후에는 300ms-800ms 정도의 생산이 진행됩니다. 이것은 저속이 가능한 n + 1 부작용과 함께 비효율적 인 쿼리로 인해 발생한다고 믿게합니다.레일스 + 몽고이드 프로덕션 환경에서 느린 쿼리

MOPED: 173.255.252.208:27017 QUERY database=* collection=orders selector= {"$query"=>{"user_id"=>"52cc529eec5cb38bbf000001"}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 batch_size=nil fields=nil (20.6976ms) 
MOPED: 173.255.252.208:27017 QUERY database=* collection=orders selector={"$query"=>{"user_id"=>"52cc529eec5cb38bbf000001"}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 batch_size=nil fields=nil (13.5436ms) 
MOPED: 173.255.252.208:27017 COMMAND  database=* command={:count=>"orders", :query=>{"user_id"=>"52cc529eec5cb38bbf000001"}} (18.1813ms) 
MOPED: 173.255.252.208:27017 QUERY  database=* collection=orders selector={"$query"=>{"user_id"=>"52cc529eec5cb38bbf000001"}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 batch_size=nil fields=nil (15.9233ms) 
MOPED: 173.255.252.208:27017 QUERY  database=* collection=orders selector={"$query"=>{"user_id"=>"52cc529eec5cb38bbf000001"}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 batch_size=nil fields=nil (29.9242ms) 
MOPED: 173.255.252.208:27017 QUERY  database=* collection=orders selector={"$query"=>{"user_id"=>"52cc529eec5cb38bbf000001"}, "$orderby"=>{:_id=>1}} flags=[] limit=0 skip=0 batch_size=nil fields=nil (69.3288ms) 

왜 주문 수집이 너무 느린 쿼리 것, 이것은 그러나, 속도 저하의 원인 일의 대량처럼 보인다 : 여기 내 제품의 API를 쳤을 때 일어나는의 스냅 샷입니다? 다음() MongoDB를에서 통계입니다 :

db.orders.stats() 
{ 
    "ns" : "orders", 
    "count" : 21535, 
    "size" : 15068736, 
    "avgObjSize" : 699.7323426979336, 
    "storageSize" : 23617536, 
    "numExtents" : 7, 
    "nindexes" : 3, 
    "lastExtentSize" : 9555968, 
    "paddingFactor" : 1.025000000000004, 
    "systemFlags" : 1, 
    "userFlags" : 0, 
    "totalIndexSize" : 5567856, 
    "indexSizes" : { 
     "_id_" : 711312, 
     "order_number_index" : 972944, 
     "_keywords_1" : 3883600 
    }, 
    "ok" : 1 
} 

컬렉션 자체가 아주 작은 (22K 레코드) 것 때문에 쿼리가 느린 이유는에 관해서는 혼란. 보시다시피, 컬렉션에 인덱스를 추가 했으므로 쿼리 속도를 향상시키기 위해 할 수있는 일에 대해 고민하고 있습니다. 도움을 많이 주시면 감사하겠습니다! 고맙습니다!

+0

어떤 Mongo 버전을 사용하고 있습니까? – cenouro

답변

0

user_id를 기준으로 주문을 조회하는 중 user_id에 색인을 추가하는 것이 좋습니다. 색인 생성 { user_id: 1 }이 좋을 것입니다.

앱 내에 관련 코드를 게시 한 경우 n + 1 쿼리인지 쉽게 알 수 있습니다. 그러나 주문 콜렉션을 여러 번 조회하기 때문에 그럴 수도 있습니다. 보다 효율적인 질의는 user_id가 user_id의 배열에있는 주문을 선택하는 것입니다. 열망하는로드에 대한 몽고드 문서는 here을 참조하십시오. 기본적으로 사용자가 User.all.each { |u| puts u.orders }과 같은 주문을 반복하는 경우 .each 앞에 .includes(:orders)을 추가하면 훨씬 효율적으로 만들 수 있습니다.

여전히 느린 문제가있는 경우 데이터베이스를 쿼리하는 코드 줄을 가져 와서 콘솔에서 .explain을 실행하면 유용 할 수 있습니다. 결과를 이해하는 데 도움이 필요하시면 here을, 3.0 대신 2.6을 사용하는 경우 here을 참조하십시오. 가장 중요한 것은 스캔되는 문서의 수 대 출력의 기준과 일치하는 문서의 수입니다. 예를 들어 21535 개의 문서가 있고 user_id에 색인이 없다면 매번 21535 개의 문서를 모두 검색하여 해당 user_id와 일치하는 문서를 찾습니다. 색인을 추가하면 계획 섹션에서 색인을 사용하는 경우 .explain이 표시됩니다.

관련 문제