mongodb - 百万数据aggregate group sum 统计超级耗时的问题,求解决方案
PHPz
PHPz 2017-05-02 09:20:16
0
3
1882

1、文档结构示例

{
    _id: xxxx,
    user: 'xiaoming',
    level: 5,
    from: 'iPhone',
    info: 'something wrong'
}

2、场景:user为'xiaoming'的文档有六七百万条

3、问题:怎么提升aggregate+group+sum速度

aggregate([
    {$match:{user: 'xiaoming', info:{$regex:'wrong'}}},
    {$group:{_id:null, count:{$sum:1}}}
])

用上面这个来统计xiaoming带有wrong的文档数量,结果

{"_id": null, "count": 2299999 }

耗时30s-40s。user、info、user+info三种索引都尝试过,速度都没有提升
baidu、google查到‘带条件计数慢无解’
怎么提升效率,10s以内能实现吗

PHPz
PHPz

学习是最好的投资!

모든 응답(3)
洪涛

가장 먼저 주목해야 할 점은 OLAP 유형의 작업에 대한 기대치가 너무 높아서는 안 된다는 것입니다. 결국 이는 대용량 데이터를 다루는 작업이기 때문에 IO만으로는 일반적인 OLTP 작업을 훨씬 뛰어넘기 때문에 OLTP 작업의 속도와 동시성을 요구하는 것은 비현실적이며 의미가 없습니다. 하지만 그렇다고 해서 최적화할 여지가 없다는 의미는 아닙니다.
색인부터 시작해 보겠습니다. 색인 없이 {user: "xiaoming"} 항목 600만 개를 찾는 데 얼마나 걸리나요? 전체 테이블 스캔COLLSCAN700만 개의 데이터에서 600만 개의 데이터를 찾는 것과 1억 개의 데이터에서 600만 개의 데이터를 찾는 것은 분명히 두 가지 개념입니다. 히트 인덱스 IXSCAN, 이 차이는 훨씬 작아서 거의 무시할 수 있습니다. 따라서 이 인덱스가 효과가 없다고 {user: 1}라고 말하는 것은 잘못된 것입니다. 단지 컬렉션의 데이터 양이 너무 작아서 차이를 볼 수 없기 때문일 수도 있습니다. 그런데 효율성에 차이가 있는지 보려면 실행 시간이 정확하지 않기 때문에 실행 시간이 아닌 실행 계획을 봐야 한다는 점을 언급해야 한다.
user 색인으로는 아직 600만 개의 결과가 있고 나머지 부분은 regex입니다. regex은 색인에 도달할 수 없으므로 info에 대한 색인이 있는지 여부는 의미가 없습니다. 600만 개의 데이터를 찾은 후 600만 개의 데이터에 대해 또 다른 filter 연산이 있습니다. 이 작업에 도움이 될 수 있는 유일한 것은 全文索引이지만 전체 텍스트 인덱싱이 정규식을 완전히 대체할 수는 없습니다. 특정 문제에 대해서는 설명서를 읽어야 합니다. 전체 텍스트 인덱싱이 가능하다면 복합 인덱스를 설정할 수 있습니다.

으아악

해당 검색어는 다음과 같이 변경되어야 합니다.

으아악

복합 전체 텍스트 색인에 대한 소개는 여기를 참조하세요. 아직 주의해야 할 몇 가지 제한 사항이 있습니다. 이번 최적화 이후에는 동일한 하드웨어 하에서 시간이 20초 미만으로 단축될 수 있을 것으로 예상되는데, 이는 여전히 원하는 10초와는 거리가 멀습니다. 처음에 언급했듯이 OLAP에 대해서는 그렇게 큰 기대를 가질 수 없습니다. 정말로 이러한 필요성이 있는 경우 소스에서 시작하여 다음을 고려해야 합니다.

  1. info 필드가 업데이트되거나 삽입될 때마다 계산됩니다.
    또는

  2. 가끔씩 완전한 통계를 작성하고 통계 결과를 캐시하여 쿼리 중에 사용자에게 직접 표시합니다

某草草

잘 모르겠는데, 두 경기로 나눠서 하면 더 좋겠죠? .

와 유사 으아악

제가 생각하는 가장 중요한 것은 시간을 갖는 것입니다.
인덱스가 있으면 인덱스 사용자입니다.

给我你的怀抱

실시간 요구 사항이 높지 않으며 정기적으로 계산되고 캐시될 수 있습니다

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿