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以内能实现吗
가장 먼저 주목해야 할 점은 OLAP 유형의 작업에 대한 기대치가 너무 높아서는 안 된다는 것입니다. 결국 이는 대용량 데이터를 다루는 작업이기 때문에 IO만으로는 일반적인 OLTP 작업을 훨씬 뛰어넘기 때문에 OLTP 작업의 속도와 동시성을 요구하는 것은 비현실적이며 의미가 없습니다. 하지만 그렇다고 해서 최적화할 여지가 없다는 의미는 아닙니다.
으아악색인부터 시작해 보겠습니다. 색인 없이
{user: "xiaoming"}
항목 600만 개를 찾는 데 얼마나 걸리나요? 전체 테이블 스캔COLLSCAN
700만 개의 데이터에서 600만 개의 데이터를 찾는 것과 1억 개의 데이터에서 600만 개의 데이터를 찾는 것은 분명히 두 가지 개념입니다. 히트 인덱스IXSCAN
, 이 차이는 훨씬 작아서 거의 무시할 수 있습니다. 따라서 이 인덱스가 효과가 없다고{user: 1}
라고 말하는 것은 잘못된 것입니다. 단지 컬렉션의 데이터 양이 너무 작아서 차이를 볼 수 없기 때문일 수도 있습니다. 그런데 효율성에 차이가 있는지 보려면 실행 시간이 정확하지 않기 때문에 실행 시간이 아닌 실행 계획을 봐야 한다는 점을 언급해야 한다.user
색인으로는 아직 600만 개의 결과가 있고 나머지 부분은regex
입니다.regex
은 색인에 도달할 수 없으므로info
에 대한 색인이 있는지 여부는 의미가 없습니다. 600만 개의 데이터를 찾은 후 600만 개의 데이터에 대해 또 다른filter
연산이 있습니다. 이 작업에 도움이 될 수 있는 유일한 것은全文索引
이지만 전체 텍스트 인덱싱이 정규식을 완전히 대체할 수는 없습니다. 특정 문제에 대해서는 설명서를 읽어야 합니다. 전체 텍스트 인덱싱이 가능하다면 복합 인덱스를 설정할 수 있습니다.해당 검색어는 다음과 같이 변경되어야 합니다.
으아악복합 전체 텍스트 색인에 대한 소개는 여기를 참조하세요. 아직 주의해야 할 몇 가지 제한 사항이 있습니다. 이번 최적화 이후에는 동일한 하드웨어 하에서 시간이 20초 미만으로 단축될 수 있을 것으로 예상되는데, 이는 여전히 원하는 10초와는 거리가 멀습니다. 처음에 언급했듯이 OLAP에 대해서는 그렇게 큰 기대를 가질 수 없습니다. 정말로 이러한 필요성이 있는 경우 소스에서 시작하여 다음을 고려해야 합니다.
info
필드가 업데이트되거나 삽입될 때마다 계산됩니다.또는
가끔씩 완전한 통계를 작성하고 통계 결과를 캐시하여 쿼리 중에 사용자에게 직접 표시합니다
잘 모르겠는데, 두 경기로 나눠서 하면 더 좋겠죠? .
와 유사 으아악제가 생각하는 가장 중요한 것은 시간을 갖는 것입니다.
인덱스가 있으면 인덱스 사용자입니다.
실시간 요구 사항이 높지 않으며 정기적으로 계산되고 캐시될 수 있습니다