MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Как работи сортирането с индекс в MongoDB?

Индексите в MongoDB се съхраняват в структура на B-дърво, където всеки вход в индекс сочи към конкретно място на диска. Използването на структура на B-дърво означава също, че индексът на MongoDB се съхранява в сортиран ред, винаги се преминава в ред и е евтино за MongoDB да извлича серия от документи в сортиран ред чрез индекси.

Актуализиране :Структурата на B-дърво е вярна за MMAPv1 механизма за съхранение, но се реализира малко по-различно от механизма за съхранение на WiredTiger (по подразбиране от MongoDB 3.2). Основната идея остава същата, където е евтино да преминете през индекса в сортиран ред.

A SORT етап (т.е. сортиране в паметта) в заявка е ограничен до 32MB използване на паметта. Заявката ще бъде неуспешна, ако SORT етап надвишава тази граница. Това ограничение може да бъде заобиколено чрез използване на сортирания характер на индексите, така че MongoDB да може да върне заявка с sort() параметър без извършване на сортиране в паметта.

Да приемем, че заявката е във формата:

    db.a.find({b:{$gt:100}, c:{$gt:200}}).sort(...)

с колекция a с индекс от:

    db.a.createIndex({b:1,c:1})

Има два възможни сценария, когато sort() етап е посочен в заявката:

1. MongoDB не може да използва сортирания характер на индекса и трябва да извърши SORT в паметта етапа .

Това е резултатът, ако заявката не може да използва "индексния префикс". Например:

    db.a.find({b:{$gt:100}, c:{$gt:200}}).sort({c:1})

В заявката по-горе индексът {b:1,c:1} може да се използва за:

  • Свържете документи с b по-голямо от 100 за {b:{$gt:100}} част от заявката.
  • Въпреки това, няма гаранция, че върнатите документи са сортирани по отношение на c .

Следователно MongoDB няма друг избор, освен да извърши сортиране в паметта. explain() изходът на тази заявка ще има SORT сцена. Това SORT етап ще бъде ограничен до 32MB използване на паметта.

2. MongoDB може да използва сортирания характер на индекса .

Това е резултатът, ако заявката използва:

  • Ключове за сортиране, които съответстват на реда на индекса, и
  • Указва същия ред като индекса (т.е. индекса {b:1,c:1} може да се използва за sort({b:1,c:1}) или sort({b:-1,c:-1}) но не и sort({b:1,c:-1}) )

Например:

    db.a.find({b:{$gt:100}, c:{$gt:200}}).sort({b:1})

В заявката по-горе индексът {b:1,c:1} може да се използва за:

  • Свържете документи с b по-голямо от 100 за {b:{$gt:100}} част от заявката.
  • В този случай MongoDB може да гарантира, че върнатите документи са сортирани по отношение на b .

explain() изходът на заявката по-горе ще не имат SORT сцена. Също така, explain() изход на заявката със и без sort() са идентични . По същество получаваме sort() безплатно.

Полезен ресурс за разбиране на тази тема е Оптимизирането на съставните индекси на MongoDB. Моля, имайте предвид, че тази публикация в блога е написана още през 2012 г. Въпреки че част от терминологията може да е остаряла, техническите характеристики на публикацията все още са уместни.

Актуализация на последващи въпроси

  1. MongoDB използва само един индекс за повечето заявки. Така например, за да избегнете SORT в паметта етап в заявката

    db.a.find({a:1}).sort({b:1})
    

    индексът трябва да покрива и двата a и b полета по едно и също време; напр. съставен индекс като {a:1,b:1} изисква се. Не можете да имате два отделни индекса {a:1} и {b:1} и очаквайте {a:1} индекс, който ще се използва за частта за равенство, и {b:1} индекс, който да се използва за частта за сортиране. В този случай MongoDB ще избере един от двата индекса.

    Следователно е правилно резултатите да се сортират, защото се търсят и връщат в реда на индекса.

  2. За да избегнете сортиране в паметта с помощта на съставен индекс, първата част на индекса трябва да отговаря на частта за равенство на заявката, а втората част трябва да отговаря на частта за сортиране на заявката (както е показано в обяснението за (1) по-горе).

    Ако имате запитване като това:

    db.a.find({}).sort({a:1})
    

    индексът {a:1,b:1} може да се използва за частта за сортиране (тъй като основно връщате цялата колекция). И ако вашата заявка изглежда така:

    db.a.find({a:1}).sort({b:1})
    

    същия индекс {a:1,b:1} може да се използва и за двете части на заявката. Също така:

    db.a.find({a:1,b:1})
    

    може също да използва същия индекс {a:1,b:1}

    Забележете модела тук:find() последвано от sort() параметрите следват реда на индекса {a:1,b:1} . Следователно съставният индекс трябва да бъде подреден по равенство -> сортиране .

Актуализация относно сортирането на различни видове

Ако полето има различни типове между документите (напр. if a е низ в един документ, число в други, булев в друг), как протича сортирането?

Отговорът е ред за сравнение на типа MongoDB BSON. За да перифразирам страницата с ръководството, редът е:

  1. MinKey (вътрешен тип)
  2. Null
  3. Числа (цели, дълги, двойни, десетични)
  4. Символ, низ
  5. Обект
  6. Масив
  7. BinData
  8. ObjectId
  9. Булева
  10. Дата
  11. Часово клеймо
  12. Регулярен израз
  13. MaxKey (вътрешен тип)

Така че от примера по-горе, използвайки възходящ ред, първо ще се появят документи, съдържащи числа, след това низове, след това булеви.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Актуализирайте полето MongoDB, като използвате стойност на друго поле

  2. MongoDB:как да преброим броя на ключовете в документ?

  3. Метеор има ли отделна заявка за колекции?

  4. Географски разпределени комплекти реплики на MongoDB за 100% време на работа

  5. MongoDB Node findone как да се справя без резултати?