Por que é necessário?
Quando os dados são armazenados em dispositivos de armazenamento baseados em disco, eles são armazenados como blocos de dados. Esses blocos são acessados por inteiro, tornando-os a operação de acesso a disco atômico. Os blocos de disco são estruturados da mesma maneira que as listas vinculadas; ambos contêm uma seção para dados, um ponteiro para o local do próximo nó (ou bloco) e ambos não precisam ser armazenados contiguamente.
Devido ao fato de que vários registros só podem ser classificados em um campo, podemos afirmar que a pesquisa em um campo não classificado exige uma Pesquisa Linear que requer N/2
acesso a blocos (em média), onde N
está o número de blocos que a mesa se estende. Se esse campo for um campo não-chave (ou seja, não contém entradas exclusivas), todo o espaço de tabela deve ser pesquisado nos N
acessos de bloco.
Enquanto que com um campo classificado, uma Pesquisa Binária pode ser usada, com log2 N
acesso a blocos. Além disso, como os dados são classificados com um campo sem chave, o restante da tabela não precisa ser pesquisado em busca de valores duplicados, uma vez que um valor mais alto é encontrado. Assim, o aumento de desempenho é substancial.
O que é indexação?
A indexação é uma maneira de classificar vários registros em vários campos. Criar um índice em um campo em uma tabela cria outra estrutura de dados que contém o valor do campo e um ponteiro para o registro ao qual ele se relaciona. Essa estrutura de índice é então classificada, permitindo que pesquisas binárias sejam executadas nela.
A desvantagem da indexação é que esses índices requerem espaço adicional no disco, uma vez que os índices são armazenados juntos em uma tabela usando o mecanismo MyISAM, esse arquivo pode atingir rapidamente os limites de tamanho do sistema de arquivos subjacente se muitos campos da mesma tabela forem indexados .
Como funciona?
Primeiramente, vamos descrever um esquema de tabela de banco de dados de amostra;
Nome do campo Tipo de dados Tamanho no disco
id (chave primária) INT não assinado 4 bytes
firstName Char (50) 50 bytes
lastName Char (50) 50 bytes
emailAddress Char (100) 100 bytes
Nota : char foi usado no lugar de varchar para permitir um tamanho exato no valor do disco. Este banco de dados de amostra contém cinco milhões de linhas e não é indexado. O desempenho de várias consultas agora será analisado. Trata-se de uma consulta usando o ID (um campo de chave classificada) e uma usando o firstName (um campo não classificado sem chave).
Exemplo 1 - campos classificados versus não classificados
Dado o nosso banco de dados de amostra de r = 5,000,000
registros de tamanho fixo, fornecendo um comprimento de registro de R = 204
bytes, eles são armazenados em uma tabela usando o mecanismo MyISAM, que usa os B = 1,024
bytes de tamanho de bloco padrão . O fator de bloqueio da tabela seria bfr = (B/R) = 1024/204 = 5
registros por bloco de disco. O número total de blocos necessários para manter a tabela é de N = (r/bfr) = 5000000/5 = 1,000,000
blocos.
Uma pesquisa linear no campo de identificação exigiria uma média de N/2 = 500,000
acessos de bloco para encontrar um valor, dado que o campo de identificação é um campo-chave. Mas como o campo id também é classificado, uma pesquisa binária pode ser realizada, exigindo uma média de log2 1000000 = 19.93 = 20
acessos de bloco. Instantaneamente, podemos ver que isso é uma melhoria drástica.
Agora, o campo firstName não é classificado nem é um campo-chave, portanto, uma pesquisa binária é impossível, nem os valores são exclusivos e, portanto, a tabela exigirá uma pesquisa até o final para N = 1,000,000
acessar exatamente um bloco. É essa situação que a indexação visa corrigir.
Dado que um registro de índice contém apenas o campo indexado e um ponteiro para o registro original, é lógico que será menor que o registro de vários campos para o qual aponta. Portanto, o próprio índice requer menos blocos de disco que a tabela original, o que exige menos acessos de bloco para iterar. O esquema para um índice no campo firstName é descrito abaixo;
Nome do campo Tipo de dados Tamanho no disco
firstName Char (50) 50 bytes
(apontador de registro) 4 bytes especiais
Nota : Os ponteiros no MySQL têm 2, 3, 4 ou 5 bytes de comprimento, dependendo do tamanho da tabela.
Exemplo 2 - indexação
Dado o nosso banco de dados de amostra de r = 5,000,000
registros com um comprimento de registro de índice de R = 54
bytes e usando o tamanho padrão do bloco B = 1,024
bytes. O fator de bloqueio do índice seria bfr = (B/R) = 1024/54 = 18
registros por bloco de disco. O número total de blocos necessários para manter o índice é de N = (r/bfr) = 5000000/18 = 277,778
blocos.
Agora, uma pesquisa usando o campo firstName pode utilizar o índice para aumentar o desempenho. Isso permite uma pesquisa binária do índice com uma média de log2 277778 = 18.08 = 19
acessos de bloco. Para localizar o endereço do registro real, que exige um acesso adicional ao bloco para leitura, elevando o total para o 19 + 1 = 20
acesso a blocos, está muito distante dos 1.000.000 acessos de bloco necessários para encontrar uma correspondência firstName na tabela não indexada.
Quando deve ser usado?
Dado que a criação de um índice requer espaço em disco adicional (277.778 blocos a mais do exemplo acima, um aumento de ~ 28%) e que muitos índices podem causar problemas decorrentes dos limites de tamanho dos sistemas de arquivos, é necessário ter cuidado para selecionar a opção correta. campos para indexar.
Como os índices são usados apenas para acelerar a procura de um campo correspondente nos registros, é lógico que os campos de indexação usados apenas para saída seriam simplesmente um desperdício de espaço em disco e tempo de processamento ao executar uma operação de inserção ou exclusão e, portanto, Deveria ser evitado. Também dada a natureza de uma pesquisa binária, é importante a cardinalidade ou exclusividade dos dados. A indexação em um campo com cardinalidade 2 dividiria os dados pela metade, enquanto uma cardinalidade 1.000 retornaria aproximadamente 1.000 registros. Com uma cardinalidade tão baixa, a eficácia é reduzida para uma classificação linear e o otimizador de consulta evitará o uso do índice se a cardinalidade for menor que 30% do número do registro, tornando o índice um desperdício de espaço.