chave primária e índice sql


106

Digamos que eu tenha uma linha de ID (int) em um banco de dados definida como a chave primária. Se eu consultar o ID com frequência, também preciso indexá-lo? Ou por ser uma chave primária significa que já está indexada?

A razão pela qual pergunto é porque no MS SQL Server posso criar um índice neste ID, que, como afirmei, é minha chave primária.

Editar: uma pergunta adicional - causará algum dano indexar adicionalmente a chave primária?

Respostas:


73

Você está certo, é confuso que o SQL Server permita que você crie índices duplicados no (s) mesmo (s) campo (s). Mas o fato de você poder criar outro não indica que o índice PK também não exista.

O índice adicional não é bom, mas o único dano (muito pequeno) é o tamanho do arquivo adicional e a sobrecarga de criação de linha.


39
Os danos dos índices não utilizados são muito prejudiciais. Por um lado, os índices consomem armazenamento. Por outro lado, ele retarda as gravações e atualizações. Sempre exclua os índices que não serão usados.
Pacerier

50

Como todo mundo já disse, as chaves primárias são indexadas automaticamente.

Criar mais índices na coluna de chave primária só faz sentido quando você precisa otimizar uma consulta que usa a chave primária e algumas outras colunas específicas. Ao criar outro índice na coluna de chave primária e incluir algumas outras colunas com ele, você pode alcançar a otimização desejada para uma consulta.

Por exemplo, você tem uma tabela com muitas colunas, mas está apenas consultando as colunas de ID, Nome e Endereço. Tomando ID como a chave primária, podemos criar o seguinte índice que é construído em ID, mas inclui colunas de nome e endereço.

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

Então, quando você usa esta consulta:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

O SQL Server fornecerá o resultado apenas usando o índice que você criou e não lerá nada da tabela real.


28

NOTA: Esta resposta aborda o desenvolvimento de classe empresarial em geral .

Este é um problema de RDBMS, não apenas do SQL Server, e o comportamento pode ser muito interessante. Por um lado, embora seja comum que as chaves primárias sejam indexadas automaticamente (exclusivamente), NÃO é absoluto. Há momentos em que é essencial que uma chave primária NÃO seja indexada exclusivamente.

Na maioria dos RDBMSs, um índice exclusivo será criado automaticamente em uma chave primária, caso ainda não exista . Portanto, você pode criar seu próprio índice na coluna de chave primária antes de declará-lo como uma chave primária, então esse índice será usado (se aceitável) pelo mecanismo de banco de dados quando você aplicar a declaração de chave primária. Freqüentemente, você pode criar a chave primária e permitir que seu índice exclusivo padrão seja criado e, em seguida, criar seu próprio índice alternativo nessa coluna e, em seguida, eliminar o índice padrão.

Agora, a parte divertida - quando você NÃO quer um índice de chave primária exclusivo? Você não quer um, e não pode tolerar um, quando sua tabela adquire dados (linhas) suficientes para tornar a manutenção do índice muito cara. Isso varia com base no hardware, no mecanismo RDBMS, nas características da tabela e do banco de dados e na carga do sistema. No entanto, geralmente começa a se manifestar quando uma tabela atinge alguns milhões de linhas.

O problema essencial é que cada inserção de uma linha ou atualização da coluna da chave primária resulta em uma varredura de índice para garantir a exclusividade. Essa varredura de índice exclusivo (ou seu equivalente em qualquer RDBMS) se torna muito mais cara à medida que a tabela cresce, até que domine o desempenho da tabela.

Já lidei com esse problema muitas vezes com tabelas de até 2 bilhões de linhas, 8 TB de armazenamento e 40 milhões de inserções de linha por dia. Fui encarregado de redesenhar o sistema envolvido, o que incluiu descartar o índice de chave primária exclusivo praticamente como primeiro passo. Na verdade, a redução desse índice foi necessária na produção simplesmente para se recuperar de uma interrupção, antes mesmo de chegarmos perto de um redesenho. Essa reformulação incluiu encontrar outras maneiras de garantir a exclusividade da chave primária e fornecer acesso rápido aos dados.


E se a chave for uma chave de incremento automático int ou bigint? O SQL Server é inteligente o suficiente para não fazer uma varredura de índice exclusivo neste caso?
quillbreaker

1
@quillbreaker: um IDENTITYcampo não tem garantia de ser único. Afinal, os usuários podem inserir valores duplicados se forem usuários IDENTITY_INSERT.

Eu sei que este é um tópico antigo, mas não entendo como uma varredura de exclusividade de um índice seria uma carga tão grande no sistema. Uma varredura de árvore B + deve ser O (log n) * v onde v é sobrecarga restrita para fragmentação de índice, equilíbrio de árvore imperfeito, etc. Assim, 2 bilhões de linhas seriam log de base 2 de 2.000.000.000 (cerca de 31 buscas) vezes, digamos, 2 ou 3 ou mesmo 10. 40M inserções por dia é cerca de 462 / seg, ~ 100 IO's por inserção ... Ahh ... Oh. Entendo. E isso foi antes de SSDs generalizados.
Charles Burns de

A menos que você elimine a restrição de exclusividade, a sobrecarga de verificação de exclusividade em cada uma das linhas não seria muito maior?
Max Candocia

20

As chaves primárias são sempre indexadas por padrão.

Você pode definir uma chave primária no SQL Server 2012 usando o SQL Server Management Studio ou Transact-SQL. A criação de uma chave primária cria automaticamente um índice exclusivo, agrupado ou não agrupado correspondente.

http://technet.microsoft.com/en-us/library/ms189039.aspx


9

Aqui está a passagem do MSDN :

Quando você especifica uma restrição PRIMARY KEY para uma tabela, o Mecanismo de Banco de Dados impõe exclusividade de dados criando um índice exclusivo para as colunas de chave primária. Este índice também permite acesso rápido aos dados quando a chave primária é usada em consultas. Portanto, as chaves primárias escolhidas devem seguir as regras para a criação de índices exclusivos.


8

um PK se tornará um índice clusterizado, a menos que você especifique o não clusterizado


3

Declarar uma restrição PRIMARY KEYou UNIQUEfaz com que o SQL Server crie automaticamente um índice.

Um índice exclusivo pode ser criado sem corresponder a uma restrição, mas uma restrição (chave primária ou única) não pode existir sem ter um índice exclusivo.

A partir daqui, a criação de uma restrição irá:

  • fazer com que um índice com o mesmo nome seja criado
  • negar a eliminação do índice criado, pois a restrição não pode existir sem ele

e, ao mesmo tempo, eliminar a restrição eliminará o índice associado.

Então, há diferença real entre um PRIMARY KEYou UNIQUE INDEX:

  • NULLos valores não são permitidos PRIMARY KEY, mas permitidos no UNIQUEíndice; e como em operadores de conjunto (UNION, EXCEPT, INTERSECT), aqui o NULL = NULLque significa que você pode ter apenas um valor já que dois NULLs são encontrados como duplicatas um do outro;
  • apenas um PRIMARY KEYpode existir por tabela, enquanto 999 índices exclusivos podem ser criados
  • quando a PRIMARY KEYrestrição é criada, ela é criada como clusterizada, a menos que já haja um índice clusterizado na tabela ou NONCLUSTEREDseja usado em sua definição; quando o UNIQUEíndice é criado, ele é criado como, a NONCLUSTEREDmenos que não seja específico para ser CLUSTEREDe tal já não exista;

2

Torná-la uma chave primária também deve criar automaticamente um índice para ela.


1

Bem, no SQL Server, geralmente, a chave primária é indexada automaticamente. Isso é verdade, mas não garante uma consulta mais rápida. A chave primária proporcionará um desempenho excelente quando houver apenas 1 campo como chave primária. Mas, quando há vários campos como chave primária, o índice é baseado nesses campos.

Por exemplo: os campos A, B, C são a chave primária, portanto, quando você faz uma consulta com base nesses 3 campos em sua CLÁUSULA WHERE, o desempenho é bom, MAS quando você deseja consultar apenas o campo C na CLÁUSULA WHERE, você não obterá um bom desempenho. Portanto, para obter seu desempenho em pleno funcionamento, você precisará indexar o campo C manualmente.

Na maioria das vezes, você não verá o problema até atingir mais de 1 milhão de registros.


0

Eu tenho um banco de dados enorme sem índice (separado).

Sempre que faço uma consulta pela chave primária, os resultados são, para todos os efeitos intensivos, instantâneos.


Isso ocorre porque o PK é um índice agrupado, olhe para o seu plano de consulta
SQLMenace

0

chaves primárias são indexadas automaticamente

você pode criar índices adicionais usando o pk dependendo do seu uso

  • index zip_code, id pode ser útil se você selecionar frequentemente por zip_code e id
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.