2013-07-25 8 views
0

나는 Post라는 콜렉션을 가지고 있습니다. 나는 항상 각 문서는 이러한 필드를 갖게됩니다 매핑 시스템을 가지고 :mongoDB 인덱스 전략

  • 아이디 (INT)
  • 대상 (문자열)
  • 유형 (문자열)
  • 을 CLIENT_ID
  • USER_ID 업데이트 됨 (문자열, 11 int 타임 스탬프)
  • 생성됨 (문자열, 11 int 타임 스탬프)
  • enabled (bool)

이 모음집은 API 스키마에서 출력되도록 액세스됩니다.

그래서 몇 가지 일반적인 요청 될 수 있습니다

/post?type=image&user_id=2 
/post?updated=35234423&order_by=client_id 
/post?enabled=true&order_by=id 

은 특정 필드를 찾거나 정렬 할 필드에 그것을 만들에는 100 % 보장은 없습니다. 테이블 데이터 8GB의에 도달 할 때

최근,이 오류가 시작하기 :

"localhost:27017: too much data for sort() with no index. add an index or specify a smaller limit" 

나는 몽고의 인덱스에 대한 설명서를 살펴 보았다 및 어려운 그것과 같은 방식으로 작동하는지 이해하는 것이 발견 MySQL 인덱스.

인덱싱에서 발견 된 일부 스레드 : MongoDB - too much data for sort() with no index error은 특정 정렬 필드를 사용하여 인덱스가 맞춰 지도록 제안하는 것 같습니다. 분명히 필자의 필터링과 분류가 많은 선택 사항 일 때 나는 그것을 할 수 없다.

누군가 내 테이블의 모든 필드에 대해 색인을 생성해야하는지에 관해 확고한 해결책을 제시 할 수 있습니까? 피드백들에 대한


덕분에, 나는 자동 색인 기능을 구축하기 시작했습니다

public function get() { 

     $indices['Post'] = array(
      'fields' => 
       array(
        'id'    => array('unique' => true, 'dropDups' => true, 'background' => true), 
        'client_id'   => array('dropDups' => true, 'background' => true), 
        'image_id'   => array('dropDups' => true, 'background' => true), 
        'user_id'   => array('dropDups' => true, 'background' => true), 
        'publish_target' => array('dropDups' => true, 'background' => true), 
        'type'    => array('dropDups' => true, 'background' => true), 
        'status'   => array('dropDups' => true, 'background' => true), 
        'text'    => array('background' => true) 
       ) 
     ); 

     foreach ($indices as $key => $index) { 

      /* set the collection */ 
      $collection = $this->mongoDB->{$key}; 

      /* delete the indexes */ 
      $collection->deleteIndexes(); 

      /* loop the fields and add the index */ 
      foreach ($index['fields'] as $subKey => $data) { 
       $collection->ensureIndex($subKey, array_merge($data, array('name' => $subKey))); 
      } 
     } 
     /* return the list */ 
     return $indices; 
    } 
+0

검색어를 공유 할 수 있습니까? 분석하는데 도움이 될까요? – user10

+0

@ user10 그는 반쯤 내려다 보면 그의 quireies의 exmaples를 공유합니다. 여기가 https://jira.mongodb.org/browse/SERVER-3071이 정말 도움이 될 것입니다. – Sammaye

답변

1

불행히도 나는 인덱스와 같은 역동적 인 성격에 대한 정말 좋은 해결책을 생각할 수 없다. 그러나이 JIRA https://jira.mongodb.org/browse/SERVER-3071은 정말로 도움이 될 것입니다.

JIRA 티켓을 시청하시는 것이 좋습니다.

+0

공유 주셔서 감사합니다. – azz0r

+0

인덱스 교차점은 여기서 도움이되지 않습니다. 적어도 필드 당 인덱스가 필요하기 때문입니다. – Derick

+0

@Derick 사실, mongodb는 쿼리 당 하나의 인덱스 만 사용할 수 있기 때문에 atm 이상으로 도움이됩니다. 교차점을 사용하면 대부분의 SQL 기술자와 마찬가지로 각 필드에 인덱스를 넣고 인덱스 사용을 얻을 수 있습니다 – Sammaye

2

당신은 서버를 공격하려고하는 쿼리 어떤 종류의 선행 알아야한다. 그것 없이는 어떤 최적화 작업도 수행 할 수 없으며 현재와 같은 정렬 문제가 발생할 수 있습니다.

사용자가 갖고있는 9 개의 필드 중 하나를 기준으로 정렬을한다고하면, 각각에 대해 색인을 만들어야합니다.

/post?updated=35234423&order_by=client_id 

가에 인덱스를 설정하여 수행 할 수 있습니다 : 당신은 때때로에 대한 문제를 방지 등의 복합 인덱스를 생성 더 많은 의미가 있음을 기억해야하지만 MongoDB를에

{ updated: 1, client_id: 1 } 

인덱스 수 색인의 모든 왼쪽 필드가 조회의 일부인 경우에만 사용됩니다.

그래서 :

  • find({ 'updated' : 1 });
  • find({ 'updated' : 1, 'client_id' : 1 });
  • find({ 'updated' : 1 }).sort({ 'client_id' : 1 });

하지만하지 않는 : { updated: 1, client_id: 1 }는 최적의 작동

  • 데이터의 양을 줄이고 당신은 또한 추가로 각 쿼리에 limit()를 추가 할 수 있습니다 오류 메시지를 방지하기 위해

  • find({ 'client_id' : 1 }).sort({ 'updated' : 1 });
  • . 8MB의 결과로 UI가 많은 결과를 보여줄지 의심 스럽습니다. 따라서 limit()을 사용하는 것이 좋습니다.

    +0

    고맙습니다. 그래서 일반적인 요청에 따라 아마 25 개의 인덱스를 만들 수 있지만 그 속도는 더 느립니 까? – azz0r

    +0

    삽입/업데이트/삭제 등의 작업을 수행 할 때 인덱스를 추가하는 데 더 많은 시간이 소요됩니다. 스키마 디자인을 다시 고려할 수도 있습니다. – Derick