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

Responder a