2016-07-19 4 views
0

내가 가지고 몽구스에서 만든 컬렉션 :MongoDB를 천천히 찾아

var ethTransactionSchema = new mongoose.Schema({ 
    blockNumber: Number, 
    blockHash: String, 
    hash: String, 
    transactionIndex: Number, 
    from: String, 
    to: String, 
    value: String 
}); 
ethTransactionSchema.index({ hash: 1 }, { unique: true }); 
ethTransactionSchema.index({ from: 1 }); 
ethTransactionSchema.index({ to: 1 }); 
ethTransactionSchema.index({ blockNumber: 1, transactionIndex: 1 }); 

ethTransactionSchema.index({ from: 1, to: 1, blockNumber: 1, transactionIndex: 1 }); 
ethTransactionSchema.index({ from: 1, blockNumber: 1, transactionIndex: 1}); 

ethTransactionSchema.index({ to: 1, blockNumber: 1, transactionIndex: 1 }); 
ethTransactionSchema.index({ to: 1, blockNumber: 1 }); 

ethTransactionSchema.index({ from: 1, blockNumber: 1 }); 
ethTransactionSchema.index({ from: 1, to: 1, blockNumber: 1 }); 
ethTransactionSchema.index({ blockNumber: 1 }); 
ethTransactionSchema.index({ transactionIndex: 1 }); 

ethTransactionSchema.index({ blockNumber: -1 }); 
ethTransactionSchema.index({ to: 1, blockNumber: -1 }); 
ethTransactionSchema.index({ from: 1, blockNumber: -1 }); 
ethTransactionSchema.index({ from: 1, to: 1, blockNumber: -1 }); 

ethTransactionSchema.index({ from: 1, to: 1, blockNumber: -1, transactionIndex: -1 }); 
ethTransactionSchema.index({ from: 1, blockNumber: -1, transactionIndex: -1 }); 
ethTransactionSchema.index({ to: 1, blockNumber: -1, transactionIndex: -1 }); 

나는이 쿼리를 실행하면이 실행시

It chooses these indexes (from explain()) 
{ 
     "from" : 1, 
     "blockNumber" : 1, 
     "transactionIndex" : 1 
} 
{ 
     "to" : 1, 
     "blockNumber" : 1, 
     "transactionIndex" : 1 
} 

그러나 : 나는 뛰어난 성능을 얻을 수

find({$or: [from: '0x120a270bbc009644e35f0bb6ab13f95b8199c4ad', 
      to: '0x120a270bbc009644e35f0bb6ab13f95b8199c4ad' 
      ]}) 
    .sort({blockNumber: -1, transactionIndex: -1}).limit(20) 

을 검색어 :

find({$and: [{$or: [{from: '0x120a270bbc009644e35f0bb6ab13f95b8199c4ad'}, 
        {to: '0x120a270bbc009644e35f0bb6ab13f95b8199c4ad'} 
        ]}, 
      {blockNumber: {$lte: 1700000}} 
      ]}).sort({blockNumber:-1, transactionIndex: -1}).limit(21) 

성능이 저하되고 결과를 반환하는 데 20 초 이상 걸리는 경우가 있습니다 (대부분의 시간은 1 초 미만입니다). 시간이 초 미만에서 예측한다면

{ 
     "from": 1 
{ 
{ 
     "to": 1 
} 

그것이 허용 될 수 있지만, 첫 번째 쿼리는 완전히 받아 들일 수있는, 몇 번 20 ~ 30 초 정도 걸립니다 : 그것은 이러한 인덱스를 선택합니다. Mongo Shell에서 같은 쿼리를 실행하면 동일한 결과가 나타납니다.

누군가 해결책을 가르쳐 줄 수 있습니까? 고급에

감사합니다, P/

+1

MongoDB가 더 나은 색인을 선택하는 데 도움이되는지 확인하기 위해 정렬과 같은 쿼리의 일부를 제거하는 것으로 시작하십시오. 또한 실적이 좋은 색인을 가리 키기 위해 [힌트] (http://mongoosejs.com/docs/api.html#query_Query-hint)를 제공하는 것이 좋습니다. – robertklep

+0

첫 번째 쿼리는 가장 느린 것으로 힌트가 도움이 될 것처럼 보이지만 설명에서 2 개의 인덱스를 선택합니다. 이 2 가지를 선택할 수 있습니까? –

+0

AFAIK, 설명은 MongoDB가 사용하기로 결정한 인덱스를 보여줄 것입니다. 반드시 최상일 필요는 없습니다. 아마도 '{from : 1, to : 1, blockNumber : 1, transactionIndex : 1}'인덱스가 쿼리에 대해 더 잘 작동 할 수 있습니다. 캐시와 같은 가장 느린 사운드 인 첫 번째 쿼리가 준비 중입니다 (이후 쿼리를 수행하는 데 사용됨). – robertklep

답변

0

find().lean() 

린 명령은 일반 객체의 결과를 제공하려고합니다. 성능이 향상됩니다.

+0

이 문제는 MongoDB 셸에서도 발생하므로 Mongoose가 아니라 쿼리 자체와 관련이 있습니다. – robertklep

+0

robertklep에 따르면 문제는 쿼리에 관한 것이고 셸에서 재현되지만 내 코드에 추가하는 것이 좋은 팁입니다. –

0

문제의 해결 방법을 찾았습니다. $ 또는 쿼리를 올바르게 작동시키는 것은 불가능했습니다. 나는에 쿼리를 감소 :

find({$and: [{from: '0x120a270bbc009644e35f0bb6ab13f95b8199c4ad'}, 
      {blockNumber: {$lte: 1700000}} 
      ]}).sort({blockNumber:-1, transactionIndex: -1}).limit(21) 

과 :

find({$and: [{to: '0x120a270bbc009644e35f0bb6ab13f95b8199c4ad'}, 
      {blockNumber: {$lte: 1700000}} 
      ]}).sort({blockNumber:-1, transactionIndex: -1}).limit(21) 

가 그런 내 자신에 의해 결과를 병합합니다. 지금은 훌륭하게 작동하지만 실제 데이터베이스를 사용하고 있다고 생각합니다. 내 잘못 일 수 있습니다. 이 db는 단지 재생하는 것입니다. 복잡한 쿼리를 시도하면 충분하지 않습니다.