Xará Matheus,
Valeu pela explicação, bem nos detalhes mesmo. Só que agora fiquei
indeciso depois da resposta do Cícero. Se eu fizer o indice com os três
campos index(A, B, C), também funcionaria? Ele seria usados em consultas
A and B, A and C, C and B, somente C e somente B? As regras seriam as
mesmas que você explicou?
Em 06-12-2013 14:11, Cicero Neto escreveu:
Olá, sou DBA SR a mais de 15 anos e entendo que você poderia optar por
um índice com os 3 campos e quando precisar da pesquisa pelo campo
"C", utilize like.
Índices locais como uma PK são cravados direto na tabela e
actualizados sempre que houver alteração neste campo, como inclusão.
Índices não locais são ORBITAIS, ou seja, orbitam a tabela como
arquivos menores indicando onde está o registro.
/
A questão de *"onde está o registro"*, nada tem a ver com performance,
o que existe é PLANO DE EXECUÇÃO, que o núcleo do postgres vai
utilizar na hora da pesquisa./
Espero ter ajudado,
Caso precise de mais detalhe, passe o "CENÁRIO". Só ele pode esclarece
qual melhor forma./*
SQL É UM QUEBRA CABEÇA COM POUCAS PEÇAS!*/
serve pára ORACLE, SQL SERVER, FIREBIRD, MYSQL, POSTGRES, TERADATA,
INGRES, INFORMIX, só não serve para PROGRESS.
T+
Seja Livre!
Use OpenSource!
LineOn, Tecnologia da Informação!
http://lineonti.wordpress.com
Em 6 de dezembro de 2013 11:32, Matheus de Oliveira
<[email protected] <mailto:[email protected]>> escreveu:
2013/12/6 Fabrízio de Royes Mello <[email protected]
<mailto:[email protected]>>
On 06-12-2013 08:45, Matheus de Oliveira wrote:
2013/12/5 Matheus Saraiva <[email protected]
<mailto:[email protected]>
<mailto:[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 <http://www.dextra.com.br/postgres/>
_______________________________________________
pgbr-geral mailing list
[email protected]
<mailto:[email protected]>
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral