2013/12/6 Fabrízio de Royes Mello <[email protected]> > On 06-12-2013 08:45, Matheus de Oliveira wrote: > >> >> 2013/12/5 Matheus Saraiva <[email protected] >> <mailto:[email protected]>> >> >> >> Tendo os campos A, B, C >> >> digamos que eu crie um índice composto (A, B) e também crie um >> índice simples ( C ). Sei que se for feita uma consulta apenas com o >> campo A o indice (A, B) será usado. Mas se eu fizer uma consulta com >> filtro em (C, A), os dois índices separados serão usados? >> >> >> Eles poderão ser usados sim. Mas, como sempre, depende. Nesse caso irá >> depender de quão seletivo seu filtro é para cada campo. >> >> Vamos pensar num exemplo simples. Numa tabela com 10 milhões de >> registros, supondo que você faça: >> >> SELECT ... FROM foo WHERE a = 10 AND c = 15; >> >> O PostgreSQL vai poder usar qualquer um dos índices que você criou. Mas >> para decidir qual (ou quais) usará, ele tentará "adivinhar" quantos >> registros cada filtro retornará, da seguinte forma: >> >> 1. Quantas tuplas somente o filtro `a = 10` retorna? >> 2. Quantas tuplas somente o filtro `c = 15` retorna? >> 3. Quantas tuplas ambos filtros, `a = 10 AND c = 15` retornam? >> >> Esse "adivinhar" é baseado nas estatísticas do banco de dados (vamos >> deixar essa pra outro momento). Vamos supor alguns exemplos baseados nos >> itens acima: >> >> 1. Existem aproximadamente 1 milhão de registros com `a = 10`. >> 2. Existem aproximadamente 5 mil registros com `c = 15`. >> 3. Existem aproximadamente mil registros com ambos. >> >> Nesse caso podemos dizer (um chute) que o PostgreSQL iria preferir usar >> somente o índice em (C). Com ele iria encontrar os 5 mil registros onde >> `c = 15`, em seguida, buscaria (da tabela mesmo) os (meros) mil >> registros onde `a = 10`. Vale mais a pena do que o trabalho extra para >> navegar nos dois índices. Agora, se pensarmos diferente: >> >> 1. Existem aproximadamente 1 milhão de registros com `a = 10`. >> 2. Existem aproximadamente 800 mil registros com `c = 15`. >> 3. Existem aproximadamente 2 mil registros com ambos. >> >> Nesse último caso, se ele pegar qualquer um dos dois índices unicamente, >> ainda teria muitas tuplas para pegar da tabela, para no final ficar com >> apenas 2 mil registros. Então ele irá preferir navegar pelos dois >> índices juntos, e pegar só o que interessa da tabela. Agora, como ele >> faz isso? Da seguinte forma: >> >> 1. Navega no índice em (A,B) e busca pelos campos onde `a = 10`. Com o >> resultado, gera um bitmap marcando as páginas que casam com 1 e que não >> casam com 0 >> 2. Navega no índice em (C) e busca pelos campos onde `c = 15` e gera um >> bitmap desse resultado também. >> 3. Realiza uma operação de AND nos dois bitmaps, o que é bem rápido (são >> só bitmaps) e gera como resultado um novo bitmap, que mapeia quais são >> as páginas da tabela que contém ambos os valores. >> 4. Por fim, basta navegar nas páginas marcadas com o bitmap resultante >> do AND anterior. Nesse caso ele terá que "reverificar" cada tupla de >> cada página, mas veja que se a tabela tem 10 milhões e queremos apenas 2 >> mil registros, estamos falando de cerca de apenas 0,02% da tabela. >> >> Vale ressaltar que o PostgreSQL usa dados estatísticos para encontrar >> esses possíveis valores de retorno. Nesse caso ele não precisa da >> quantidade **exata** de registros que cada filtro retorna, mas quanto >> mais próximo do real, melhor serão os planos de execução criados. Logo, >> manter as estatísticas atualizadas é uma tarefa muito importante. >> >> > Muito legal sua resposta Matheus, vc poderia transformar em post em seu > blog hein!!! > >
kkkk... Acho que eu estava inspirado, =P. Depois que eu mandei eu pensei exatamente nisso. Vou fazer logo que montar um exemplo real também. Valeu cara. Abraços. -- Matheus de Oliveira Analista de Banco de Dados Dextra Sistemas - MPS.Br nível F! www.dextra.com.br/postgres
_______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
