Pergunta

Se eu sei que um índice terão valores exclusivos, como é que vai afetar o desempenho em inserções ou seleciona se eu declará-la como tal.

Se o otimizador sabe o índice é único como isso vai afetar o plano de consulta?

Eu entendo que especificar uniquenes pode servir para preservar a integridade, mas deixando que a discussão de lado para o momento, quais são as consequências perfomance.

Foi útil?

Solução

Para encurtar a história:. Se seus dados são intrinsecamente UNIQUE, você será beneficiado com a criação de um índice UNIQIE sobre eles

Veja o artigo em meu blog para explicação detalhada:


Agora, os detalhes.

As @Mehrdad disse, UNIQUENESS afeta a contagem de linhas estimado no construtor de plano.

índice UNIQUE tem máxima seletividade possível, é por isso:

SELECT  *
FROM    table1 t2, table2 t2
WHERE   t1.id = :myid
        AND t2.unique_indexed_field = t1.value

quase certamente irá usar NESTED LOOPS, enquanto

SELECT  *
FROM    table1 t2, table2 t2
WHERE   t1.id = :myid
        AND t2.non_unique_indexed_field = t1.value

pode beneficiar de uma HASH JOIN se o otimizador pensa que non_unique_indexed_field não é selectiva.

Se o seu índice é CLUSTERED (ou seja, as linhas theirselves estão contidos nas folhas de índice) e não-UNIQUE, em seguida, uma coluna especial escondido chamado uniquifier é adicionado a cada chave de índice, tornando assim a chave maior e o índice mais lento.

É por isso índice UNIQUE CLUSTERED é na verdade um pouco mais efficicent do que um non-UNIQUE CLUSTERED.

Em Oracle, uma junção em UNIQUE INDEX é necessário para tal chamado key preservation, o que garante que cada linha de uma tabela serão selecionados, no máximo, uma vez e faz um atualizável exibição.

Esta consulta:

UPDATE  (
        SELECT  *
        FROM    mytable t1, mytable t2
        WHERE   t2.reference = t1.unique_indexed_field
        )
SET     value = other_value

trabalhará em Oracle, enquanto este:

UPDATE  (
        SELECT  *
        FROM    mytable t1, mytable t2
        WHERE   t2.reference = t1.non_unique_indexed_field
        )
SET     value = other_value

falhará.

Este não é um problema com SQL Server, no entanto.

Mais uma coisa: para uma tabela como esta,

CREATE TABLE t_indexer (id INT NOT NULL PRIMARY KEY, uval INT NOT NULL, ival INT NOT NULL)
CREATE UNIQUE INDEX ux_indexer_ux ON t_indexer (uval)
CREATE INDEX ix_indexer_ux ON t_indexer (ival)

, esta consulta:

/* Sorts on the non-unique index first */
SELECT  TOP 1 *
FROM    t_indexer
ORDER BY
        ival, uval

usará um TOP N SORT, enquanto este:

/* Sorts on the unique index first */
SELECT  TOP 1 *
FROM    t_indexer
ORDER BY
        uval, ival

usará apenas uma verificação do índice.

Para a última consulta, não há nenhum ponto na classificação adicional sobre ival, desde uval são de qualquer maneira única, e o otimizador leva isso em conta.

Em dados de amostra de linhas 200,000 (id == uval == ival), o ex-consulta é executada para segundos 15, enquanto o último é instantânea.

Outras dicas

Claro que o otimizador terá exclusividade em consideração. Ela afeta a contagem de linhas esperado em planos de consulta.

O desempenho é afetado negativamente quando inserir dados. Ele precisa verificar a unicidade.

Eu apenas testei isso na minha máquina para uma mesa de Produção contendo mais de 1 milhão de linhas, porque achei que era um bom teste. Os resultados foram interessantes, aqui está os números brutos:

- No índice:

    Setup Time: 8888, Insert Time: 501690

- Única restrição:

    Setup Time:   42, Insert Time: 488030

A configuração consistia em obter o máximo do campo que eu estava adicionando a restrição exclusiva para - assim logicamente o desempenho foi aumentado dramaticamente adicionando a restrição. Isso também melhorar o desempenho na busca por esta chave estrangeira.

Curiosamente o tempo de inserção melhorou ligeiramente, bem como (por 2,7228%), portanto, apenas impactos positivos [no meu caso de teste] de adicionar a restrição (+ índice inerente).

Teste mostra apenas impactos positivos de adicionar a restrição -. Nenhum impacto no desempenho

NOTA:. Para o nosso sistema de teste Espero que os valores para quase sempre ser único, então eu não testar a inserção de valores não-exclusivos, nestes dados é realmente uma exceção - e não algo que precisa ser alto desempenho

Sim, ele vai ser levado em consideração pelo mecanismo de consulta.

Talvez mais importante: a singularidade irá proteger a integridade dos dados. Desempenho seria uma razão para ignorar isso.

Desempenho pode ser afetado positiva ou negativamente ou não em todos: seria depende da consulta, se o índice é usado etc

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top