MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDb:como criar o índice correto (composto) para dados com muitos campos pesquisáveis


Vou tentar explicar o que isso significa por exemplo. Os índices baseados em B-tree não são algo específico do mongodb. Em contraste, é um conceito bastante comum.

Então, quando você cria um índice - você mostra ao banco de dados uma maneira mais fácil de encontrar algo. Mas esse índice é armazenado em algum lugar com um ponteiro apontando para um local do documento original. Esta informação é ordenada e você pode vê-la como uma árvore binária que tem uma propriedade muito boa:a busca é reduzida de O(n) (varredura linear) para O(log(n)) . O que é muito mais rápido porque cada vez que cortamos nosso espaço pela metade (potencialmente podemos reduzir o tempo de 10^6 para 20 pesquisas). Por exemplo, temos uma grande coleção com o campo {a : some int, b: 'some other things'} e se indexarmos por a, acabamos com outra estrutura de dados que é classificada por a . Parece assim (com isso não quero dizer que é outra coleção, isso é apenas para demonstração):
{a : 1, pointer: to the field with a = 1}, // if a is the smallest number in the starting collection
...
{a : 999, pointer: to the field with a = 990} // assuming that 999 is the biggest field

Então agora estamos procurando por um campo a =18. Em vez de passar um por um por todos os elementos pegamos algo no meio e se for maior que 18, então estamos dividindo a parte inferior ao meio e verificando o elemento lá . Continuamos até encontrar a =18. Então olhamos para o ponteiro e sabendo dele extraímos o campo original.

A situação com índice composto é semelhante (em vez de ordenar por um elemento, ordenamos por muitos). Por exemplo, você tem uma coleção:
{ "item": 5, "location": 1, "stock": 3, 'a lot of other fields' }  // was stored at position 5 on the disk
{ "item": 1, "location": 3, "stock": 1, 'a lot of other fields' }  // position 1 on the disk
{ "item": 2, "location": 5, "stock": 7, 'a lot of other fields' }  // position 3 on the disk
... huge amount of other data
{ "item": 1, "location": 1, "stock": 1, 'a lot of other fields' }  // position 9 on the disk
{ "item": 1, "location": 1, "stock": 2, 'a lot of other fields' }  // position 7 on the disk

e deseja um índice { "item":1, "localização":1, "estoque":1 }. A tabela de pesquisa ficaria assim (mais uma vez - esta não é outra coleção, é apenas para demonstração):
{ "item": 1, "location": 1, "stock": 1, pointer = 9 }
{ "item": 1, "location": 1, "stock": 2, pointer = 7 }
{ "item": 1, "location": 3, "stock": 1, pointer = 1 }
{ "item": 2, "location": 5, "stock": 7, pointer = 3 }
.. huge amount of other data (but not necessarily here. If item would be one it would be somewhere next to items 1)
{ "item": 5, "location": 1, "stock": 3, pointer = 5 }

Veja que aqui tudo é basicamente ordenado por item, depois por localização e depois por ponteiro. Da mesma forma que com um único índice não precisamos escanear tudo. Se tivermos uma consulta que procure item = 2, location = 5 and stock = 7 podemos identificar rapidamente onde os documentos com item = 2 são e, da mesma forma, identificar rapidamente onde entre esses itens o item com location 5 e assim por diante.

E agora uma parte interessante . Também criamos apenas um índice (embora este seja um índice composto, ainda é um índice) podemos usá-lo para encontrar rapidamente o elemento
  • somente pelo item . Realmente tudo o que precisamos fazer é apenas o primeiro passo. Portanto, não faz sentido criar outro índice {location :1} porque ele já está coberto pelo índice composto.
  • também podemos encontrar rapidamente apenas por item and by location (precisamos de apenas 2 passos).

Cool 1 index, mas nos ajuda de três maneiras diferentes. Mas espere um minuto:e se quisermos encontrar por item and stock . Oh, parece que podemos acelerar essa consulta também. Podemos em log(n) encontrar todos os elementos com item específico e... aqui temos que parar - a magia terminou. Precisamos iterar através de todos eles. Mas ainda muito bom.

Mas que possa nos ajudar com outras dúvidas. Vamos ver uma consulta por location que parece já foi encomendado. Mas se você olhar para isso - verá que isso é uma bagunça. Um no começo e outro no final. Ele não pode ajudá-lo em tudo.

Espero que isso esclareça algumas coisas:
  • por que os índices são bons (reduzir o tempo de O(n) para potencialmente O(log(n))
  • por que os índices compostos podem ajudar com algumas consultas, no entanto, não criamos um índice nesse campo específico e ajudamos com algumas outras consultas.
  • quais índices são cobertos pelo índice composto
  • por que os índices podem prejudicar (cria uma estrutura de dados adicional que deve ser mantida)

E isso deve dizer outra coisa válida:o índice não é uma bala de prata . Você não pode acelerar todas as suas consultas, então parece bobagem pensar que criando índices em todos os campos TUDO seria super rápido.