2013-04-22 3 views
-1

Я пытаюсь выяснить, какой дизайн схемы я должен использовать.Встраивать или не встраивать?

(Эти примеры документов, фактические документы содержат больше свойств)

Embedded:

{ 
    _id: ObjectId(), 
    title: "trolo", 
    subs: [ 
     { 
     owner: refUserId 
     }, 
     ... 
    ] 
} 

Я индексированный по: ensureIndex({ "subs.owner": 1 })

Нормированная:

Я индексированный по: ensureIndex({ owner: 1 })

Я запустить некоторые benchRun() тесты на различных моделях. Но результат очень удивителен.

Встроенный запрос:

ops = [ 
    {op: "find", ns: t.getFullName(), query: { "subs.owner": someUserId }} 
] 

Нормированная запрос:

ops = [ 
    {op: "find", ns: t.getFullName(), query: { owner: someUserId }} 
] 

benchRun сценарий:

for (x = 1; x <= 128; x *= 2) { 
    res = benchRun({ 
     parallel : x, 
     seconds : 5, 
     ops : ops 
    }); 
    print("threads: " + x + "\t queries/sec: " + res.query); 
} 

Выход:

Embedded:

threads: 1  queries/sec: 11331 
threads: 2  queries/sec: 16764.6 
threads: 4  queries/sec: 21587 
threads: 8  queries/sec: 25198.6 
threads: 16  queries/sec: 24717.6 
threads: 32  queries/sec: 24707.4 
threads: 64  queries/sec: 25813.8 
threads: 128  queries/sec: 30785.4 

Нормированная:

threads: 1  queries/sec: 8.4 
threads: 2  queries/sec: 13.2 
threads: 4  queries/sec: 16.4 
threads: 8  queries/sec: 17.4 
threads: 16  queries/sec: 18.2 
threads: 32  queries/sec: 20.8 
threads: 64  queries/sec: 27.4 
threads: 128  queries/sec: 39.6 

Почему нормализованная модель так много медленнее? Я бы ожидал, что это будет самым быстрым.

UPDATE

Вот что .explain() должен сказать о моих запросах.

Embedded

> db.embedded.find({"subs.owner":ObjectId("516ea63322f2a93c4fef8542")}).explain() 

{ 
     "cursor" : "BasicCursor", 
     "isMultiKey" : false, 
     "n" : 5, 
     "nscannedObjects" : 5, 
     "nscanned" : 5, 
     "nscannedObjectsAllPlans" : 5, 
     "nscannedAllPlans" : 5, 
     "scanAndOrder" : false, 
     "indexOnly" : false, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "millis" : 0, 
     "indexBounds" : { 

     }, 
     "server" : "localhost:27017" 
} 

Нормированная

> db.collectionB.find({owner: ObjectId("516ea63322f2a93c4fef8542")}).explain() 
{ 
     "cursor" : "BtreeCursor owner_1", 
     "isMultiKey" : false, 
     "n" : 76625, 
     "nscannedObjects" : 76625, 
     "nscanned" : 76625, 
     "nscannedObjectsAllPlans" : 76625, 
     "nscannedAllPlans" : 76625, 
     "scanAndOrder" : false, 
     "indexOnly" : false, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "millis" : 91, 
     "indexBounds" : { 
       "owner" : [ 
         [ 
           ObjectId("516ea63322f2a93c4fef8542"), 
           ObjectId("516ea63322f2a93c4fef8542") 
         ] 
       ] 
     }, 
     "server" : "localhost:27017" 
} 
+0

Вы пытались использовать 'explain' в своих запросах, чтобы узнать, что происходит? – WiredPrairie

+0

Вот что я делаю прямо сейчас :), не знаю, почему я не думал об этом раньше.Но мой нормализованный запрос имеет 'indexOnly: false', поэтому я читаю http://docs.mongodb.org/manual/tutorial/create-indexes-to-support-queries/ –

+0

Другие недавно отметили, что' indexOnly: false' может быть очень запутанным и трудно «объяснить» [вздох] :). – WiredPrairie

ответ

0

Почему вы ожидали бы нормализуется быть быстрее? Со встроенным документом документ хранится в одном месте на диске. С помощью одного диска можно вернуть весь документ. Если он нормализуется, он распространяется по диску, и это означает, что 2 диска пытается получить информацию. В зависимости от скорости диска и секторов, к которым должна идти игла, она неизбежно будет медленнее, чем встроенная модель документа.

+0

Потому что он должен искать вложенные документы. Я заметил, что после того, как я выполнил $ unwind и $ match, производительность запустилась до 0 запросов/сек на встроенной модели. –

+0

Нет, потому что bsonspec позволяет пропускать вложенные субдокументы – sweaves

Смежные вопросы