A ordem das colunas em um índice PK importa?
Sim.
Por padrão, a restrição de chave primária é imposta no SQL Server por um índice clusterizado exclusivo. O índice clusterizado define a ordem lógica das linhas na tabela. Pode haver várias páginas de índice extras adicionadas para representar os níveis superiores do índice da árvore b, mas o nível mais baixo (folha) de um índice em cluster é simplesmente a ordem lógica dos dados.
Para ser claro, as linhas em uma página não são necessariamente fisicamente armazenadas em ordem de chave de índice em cluster. Há uma estrutura de indireção separada dentro da página que armazena um ponteiro para cada linha. Essa estrutura é classificada pelas chaves de índice em cluster. Além disso, cada página possui um ponteiro para a página anterior e a próxima no mesmo nível na ordem das chaves de índice em cluster.
Com uma chave primária em cluster de (RowNumber, DataDate)
, as linhas são classificadas logicamente primeiro por RowNumber
e depois por DataDate
- para que todas as linhas RowNumber = 1
sejam agrupadas logicamente, depois linhas onde RowNumber = 2
e assim por diante.
Quando você adiciona novos dados ( RowNumbers
de 1 a n), as novas linhas pertencem logicamente às páginas existentes; portanto, o SQL Server provavelmente precisará trabalhar muito dividindo as páginas para liberar espaço. Toda essa atividade gera muito trabalho extra (incluindo o registro das alterações) sem nenhum ganho.
As páginas divididas também começam cerca de 50% vazias; portanto, a divisão excessiva pode resultar em baixa densidade de páginas (menos linhas do que o ideal por página). Não são apenas essas más notícias para leitura do disco (densidade mais baixa = mais páginas para ler), as páginas de densidade mais baixa também ocupam mais espaço na memória quando armazenadas em cache.
Alterar o índice em cluster para (DataDate, RowNumber
) significa que novos dados (presumivelmente, mais altos DataDates
que os armazenados atualmente) são anexados ao final lógico do índice em cluster em novas páginas. Isso removerá as despesas desnecessárias da divisão de páginas e resultará em tempos de carregamento mais rápidos. Dados menos fragmentados também significam que a atividade de leitura antecipada (ler páginas do disco antes de serem necessárias para uma consulta em andamento) pode ser mais eficiente.
Se nada mais, suas consultas têm muito mais probabilidade de pesquisar do DataDate
que RowNumber
. Um índice agrupado ativado (DataDate, RowNumber
) suporta pesquisas de índice ativadas DataDate
(e depois RowNumber
). O arranjo existente apenas apóia as buscas RowNumber
(e somente então, talvez DataDate
). Você poderá soltar o índice não clusterizado existente DataDate
depois que a chave primária for alterada. O índice clusterizado será mais amplo que o índice não clusterizado que ele substitui; portanto, você deve testar para garantir que o desempenho permaneça aceitável.
Ao importar novos dados bcp
, você poderá obter um desempenho superior se os dados no arquivo de importação forem classificados pelas chaves de índice em cluster (idealmente (DataDate, RowNumber
)) e você especificar a bcp
opção:
-h "ORDER(DataDate,RowNumber), TABLOCK"
Para obter o melhor desempenho de carregamento de dados, você pode tentar obter inserções minimamente registradas. Para mais informações, veja: