O que são índices (no MongoDB e em outros SGBDs)?
Os índices são estruturas de dados especiais que armazenam uma pequena porção de um conjunto de dados da coleção em uma forma fácil de percorrer. O índice armazena o valor de um atributo específico ou conjunto de atributos.
Eles são usados para melhorar o desempenho das consultas feitas em um banco de dados.
Para entende-los é legal pensar em um livro. Imagine que você procura um capítulo especifico, e para acelerar a sua busca você irá olhar o índice do livro, encontrará nele o capítulo procurado e irá direto para a página que contém a informação que você busca. Sem o índice você precisaria olhar todas as páginas até achar o capítulo procurado.
Índices vão salvar sua vida? Algumas vezes sim, e em outras podem acabar com ela!
Você pode criar muitos índices em coleções que são lidas frequentemente! Em coleções que tem um volume muito alto de inclusões os índices precisam ser muito bem pensados porque eles podem afetar negativamente o desempenho da sua aplicação.
E se sua coleção não tem só leitura ou só escritas, pense bem nos índices que você vai criar.
Quando a sua coleção é muito grande, quando os dados estão particionados e replicados você precisa de um pouco mais de cuidado para criar seus índices, neste caso recomendo fortemente a leitura da documentação do MongoDB .
Considerações iniciais
Tenho algumas considerações básicas e aplicáveis a todos os tipos de bancos de dados.
A primeira consideração é que os índices podem ter um ou mais atributos, ou seja podem ser simples ou compostos.
Um índice pode ser criado em ordem crescente ou decrescente, por isso você informará (na maior parte dos tipos de índices) o nome do atributo usado no índice e a ordem que o índice será criado.
A maior parte dos índices pode ser criada de acordo com a sintaxe a seguir. Perceba que a criação de um índice tem duas informações principais, a primeira são os atributos que fazem parte do índice e sua ordem (1 = ordem crescente e -1 = ordem decrescente); e a segunda possui as opções que indicam por exemplo, o tipo do índice:
db.nome coleção.createIndex( { <nome atributo: ordem(1 Crescente e -1 Decrescente>, …, <nome atributo n: ordem(1 Crescente e -1 Decrescente> }, { <opções> })
Tipos de índices
Índice único
Quando você cria um documento, o MongoDB automaticamente cria um índice único, com o atributo _id. Entretanto você pode precisar criar outros índices únicos na sua coleção e para isso a sintaxe é a seguinte:
db.nome coleção.createIndex( {“nome do atributo": ordem,…,“nome do atributo n": ordem}, { unique: true } )
Índice Multikey
Imagine que o valor armazenado em um dos atributos é um array, e você precise criar um índice neste atributo. O MongoDB usa o índice multikey para indexar o conteúdo armazenado em arrays.
No caso da imagem a seguir:
O índice seria criado com a seguinte sintaxe:
db.nome coleção.createIndex({“addr.zip”:1})
Índices geoespaciais
Este tipo de índice indexa coordenadas geoespaciais. Existem 2 tipos : índices 2d que usam geometria planar ao retornar resultados e índices 2dsphere que usam geometria esférica para retornar resultados.
Para criar um índice deste tipo a sintaxe é um pouco diferente porque você deve informar o atributo que possui as coordenadas geográficas, e o tipo de índice que será usado.
Para índices 2d use a sintaxe:
db.nome coleção.createIndex( { “atributo que possui coordenadas": "2d" } )
Para índices 2dsphere use a sintaxe:
db.nome coleção.createIndex( { "atributo que possui coordenadas geográficas" : "2dsphere" } )
Text Indexes
Este é um tipo bacana de índices, porque permite a consulta otimizada em atributos da coleção que possuam um texto em seu conteúdo. Detalhe importante… Só pode existir um índice deste tipo por coleção.
Existem várias possibilidades na criação deste índice e como eu já disse antes… Veja a documentação no site do MongoDB.
db.nome coleção.createIndex( { "atributo que possui texto em seu conteúdo": "text" } )
Hashed Indexes
Existe uma situação onde o particionamento de dados (sharding) é feito usando um atributo, com valor baseado em hash gerado pelo MongoDB. Para suportar este tipo de sharding o MongoDB cria um tipo de índice chamado hashed index.
db.nome coleção.createIndex ( { _id : "hash" } )
Partial Indexes
Adoro este tipo de índice! Eles são bem bacanas quando você conhece muito bem as suas consultas e a estrutura dos documentos que existem na sua coleção.
Este tipo de índice indexa somente documentos da coleção que atendam a determinadas exprssões.
db.nome coleção.createIndex( { “nome do atributo” : ordem}, { partialFilterExpression: { expressão}} )
Sparse Indexes
Este é um tipo de índice que faz muito sentido quando lembramos que o MongoDB não possui schema. Digo isso que quando criamos este tipo de índice, serão indexados somente os documentos que contenham um determinado atributo. O índice ignora os documentos que não possuem o atributo indexado.
db.nome coleção.createIndex({“nome do atributo": 1}, { sparse: true } )
TTL Indexes
Imagine um índice que só exista durante um determinado periodo de tempo, após este período ele seja automaticamente excluídos, estes são os índices TTL. Na criação dele é preciso determinar após quantos segundos o índice será excluídos.
db.nome coleção.createIndex({“nome do atributo": 1}, { expireAfterSeconds : 3600 } )
Covered Queries
Ahhh como é legal quando crio este tipo de query!
Imagina que seu índice possui o atributo A e o atributo B. A sua consulta deve retornar o atributo A e o atributo B (na mesma ordem do índice). Neste caso a query é chamada de covered query, e é executada de forma muito rápida! Por que o MongoDB não precisa acessar a coleção, ele acessa e retorna somente o conteúdo do índice.
Conclusão
Para entender os índices vale o ditado popular “a diferença entre e o veneno e o remédio está na dosagem”, porque se a sua coleção tem a mesma proporção de leituras e escritas, os índices precisam ser pensados para que não afetem negativamente o desempenho das operações.
Agora se a sua coleção só possui leituras os índices vão ajudar muito!!! Mas ainda sim você precisa conhecer os tipos de índice que o MongoDB oferece para escolher o que melhor atende a necessidade da sua aplicação .
Acho que já evoluímos bastante com o MongoDB, e a nossa jornada com ele está quase chegando ao fim! Em 2018 começaremos a conversar sobre um outro assunto bem legal, e isso não significa que deixaremos o MongoDB de lado! Sempre que surgirem assuntos legais eu vou postar aqui 🙂
Conselho da Dani… Treine!!! Use todos os tipos de índices, faça testes, comece e recomece. faça as mesmas consultas com e sem índices, você começará a ver as diferenças.
Se você tem alguma dúvida, é só me procurar no Twitter, ou no facebook, ou comentando este post, ou no formulário de contato. Não se preocupe… Eu sempre respondo (mesmo que seja para avisar que estou pesquisando).
A cada semana você está se tornando um desenvolvedor melhor e mais capaz! Parabéns!!!
Referências
Documentação do MongoDB (https://docs.mongodb.com/manual/indexes/)