programing

집계 쿼리에 대한 MongoDB의 성능

batch 2023. 7. 15. 09:58
반응형

집계 쿼리에 대한 MongoDB의 성능

MongoDB의 성과에 대해 많은 좋은 이야기를 들은 후, 우리는 Mongodb에게 우리가 가지고 있는 문제를 해결하기 위해 노력하기로 결정했습니다.저는 여러 mysql 데이터베이스에 있는 모든 기록을 mongodb의 단일 컬렉션으로 옮기는 것으로 시작했습니다.그 결과 HD에서 약 100GB의 공간을 차지하는 2,900만 개의 문서(각 문서에는 최소 20개의 필드가 있음)가 수집되었습니다.우리는 모든 문서가 동일한 구조를 가지고 있고 모든 문서에 대한 결과를 쿼리하고 집계하기를 원하기 때문에 모든 문서를 하나의 컬렉션에 포함하기로 결정했습니다.

쿼리와 일치하도록 인덱스를 몇 개 만들었습니다. 그렇지 않으면 단순한 카운트()도 오래 걸립니다.그러나 distinct() 및 group()과 같은 쿼리는 여전히 너무 오래 걸립니다.

예:

// creation of a compound index    
db.collection.ensureIndex({'metadata.system':1, 'metadata.company':1})

// query to get all the combinations companies and systems
db.collection.group({key: { 'metadata.system':true, 'metadata.company':true }, reduce: function(obj,prev) {}, initial: {} });

mongod 로그를 봤는데 다음과 같은 행이 많이 있습니다(위 쿼리 실행 중).

Thu Apr  8 14:40:05 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1048890 nreturned:417 154ms
Thu Apr  8 14:40:08 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1050205 nreturned:414 430ms
Thu Apr  8 14:40:18 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1049748 nreturned:201 130ms
Thu Apr  8 14:40:27 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1051925 nreturned:221 118ms
Thu Apr  8 14:40:30 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1053096 nreturned:250 164ms
...
Thu Apr  8 15:04:18 query database.$cmd ntoreturn:1 command  reslen:4130 1475894ms

이 쿼리는 1475894ms가 소요되었으며, 이는 제가 예상했던 것보다 훨씬 길었습니다(결과 목록에 약 60개 항목이 있음).우선, 제 컬렉션에 있는 문서의 수가 많은 것을 감안할 때 이것은 예상되는 것입니까?일반적으로 mongodb에서 집계 쿼리가 그렇게 느릴 것으로 예상됩니까?어떻게 하면 성능을 향상시킬 수 있을까요?

저는 듀얼 코어와 10GB의 메모리를 갖춘 단일 기계에서 mongod를 실행하고 있습니다.

감사해요.

이 방법은 여러 시스템에 분산된 샤드 데이터베이스에서 MapReduce를 사용하여 집계 쿼리의 성능을 향상시키는 것입니다.

Mongo's Mapreduce의 성능을 동일한 기계에 있는 Oracle의 Group by Select 문과 비교했습니다.저는 Mongo가 대략 25배 느리다는 것을 알았습니다.즉, Oracle이 단일 시스템에서 제공하는 것과 동일한 성능을 Mongo와 함께 사용하려면 최소 25대의 시스템에서 데이터를 샤딩해야 합니다.약 1,400만 개의 문서/행이 있는 수집/테이블을 사용했습니다.

mongoexport.exe를 통해 mongo에서 데이터를 내보내고 내보낸 데이터를 Oracle에서 외부 테이블로 사용하고 Oracle에서 그룹바이를 수행하는 것이 Mongo의 자체 MapReduce를 사용하는 것보다 훨씬 빨랐습니다.

몇 가지.

그룹 쿼리에서 많은 데이터를 처리하고 있습니다.결과 집합은 작지만 이 작은 결과를 생성하기 위해 수집된 모든 데이터를 표로 축척하는 것처럼 보입니다.이것이 아마도 속도 저하의 근본 원인일 것입니다.이 속도를 높이기 위해 쿼리가 실행되는 동안 iOSstat을 통해 서버의 디스크 성능을 확인하는 것이 병목 현상일 가능성이 높습니다.

다른 답변에서 지적했듯이 group 명령어는 Javascript 인터프리터를 사용하므로 성능이 제한됩니다.2.1에서 베타로 릴리스된 새 집계 프레임워크를 사용해 볼 수도 있습니다(참고: 이는 2012년 2월 24일 현재 불안정한 릴리스입니다).좋은 소개는 http://blog.mongodb.org/post/16015854270/operations-in-the-new-aggregation-framework 을 참조하십시오.이것은 (1)의 데이터 볼륨 문제를 극복할 수는 없지만 C++로 구현되며 javascript 시간이 병목 현상이라면 훨씬 더 빠를 것입니다.

또 다른 방법은 증분 맵 축소를 사용하여 그룹화된 결과로 두 번째 컬렉션을 생성하는 것입니다.즉, 맵 축소 작업을 실행하여 결과를 한 번 집계한 다음 새 데이터를 기존 컬렉션으로 다시 줄이는 다른 맵 축소 작업을 주기적으로 실행하는 것입니다.그러면 매번 그룹 명령을 실행하는 대신 앱에서 이 두 번째 컬렉션을 쿼리할 수 있습니다.

집계(맵 축소 또는 기타)는 데이터베이스 엔진이 아닌 Javascript VM에 의해 수행되기 때문에 mongo에서 매우 느립니다.이는 시계열 데이터에 대한 이(매우 양호한, imo) DB의 제한 사항으로 계속 적용됩니다.

언급URL : https://stackoverflow.com/questions/2599943/mongodbs-performance-on-aggregation-queries

반응형