As colunas não relevantes afetam o tempo de consulta das instruções de seleção?

10

Eu só estou curioso.

Digamos que você tenha uma tabela de 1 milhão de registros / linhas.

select order_value from store.orders

Faz diferença se essa tabela possui 1 campo, 2 campos ou 100 campos no tempo real da consulta? Quero dizer todos os campos, exceto "order_value".

No momento, estou enviando dados para um data warehouse. Às vezes, despejo campos na tabela que "podem ser usados ​​no futuro, algum dia" - mas eles não estão sendo consultados agora, por nada. Esses campos 'estranhos' afetam instruções selecionadas que não as incluem, direta ou indiretamente (não * quero dizer)?

user45867
fonte
Há toneladas de informações sobre isso disponíveis na web. A chave é obter as informações mais recentes à medida que a tecnologia muda. O que você está perguntando depende tanto da sua configuração específica que não é possível dar uma resposta muito boa. Um ponto importante a ser lembrado é que, ao mudarmos para o SSD, muitas coisas que antes eram muito importantes para o desempenho não são mais o caso.
Joe

Respostas:

10

Isso realmente depende de índices e tipos de dados.

Usando o banco de dados Stack Overflow como exemplo, é assim que a tabela Usuários se parece:

NUTS

Tem um PK / CX na coluna Id. Portanto, são todos os dados da tabela classificados por ID.

Com isso como o único índice, o SQL precisa ler a coisa toda (sem as colunas LOB) na memória, se ainda não estiver lá.

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SET STATISTICS TIME, IO ON 

SELECT u.Id
INTO  #crap1
FROM dbo.Users AS u

O tempo de estatísticas e o perfil io são assim:

Table 'Users'. Scan count 7, logical reads 80846, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2406 ms,  elapsed time = 446 ms.

Se eu adicionar um índice não clusterizado adicional apenas no ID

CREATE INDEX ix_whatever ON dbo.Users (Id)

Agora tenho um índice muito menor que satisfaz minha consulta.

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SELECT u.Id
INTO  #crap2
FROM dbo.Users AS u

O perfil aqui:

Table 'Users'. Scan count 7, logical reads 6587, physical reads 0, read-ahead reads 6549, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2344 ms,  elapsed time = 384 ms.

Podemos fazer muito menos leituras e economizar um pouco de tempo de CPU.

Sem mais informações sobre sua definição de tabela, não posso realmente reproduzir o que você está tentando medir melhor.

Mas você está dizendo que, a menos que exista um índice específico nessa coluna, as outras colunas / campos também serão verificadas? Isso é apenas uma desvantagem inerente ao design de tabelas rowstore? Por que campos irrelevantes seriam verificados?

Sim, isso é específico para tabelas rowstore. Os dados são armazenados pela linha nas páginas de dados. Mesmo que outros dados na página sejam irrelevantes para sua consulta, toda a linha> página> índice precisa ser lida na memória. Eu não diria que as outras colunas são "digitalizadas" tanto quanto as páginas em que existem são digitalizadas para recuperar o valor único nelas relevante para a consulta.

Usando o exemplo da lista telefônica antiga: mesmo que você esteja apenas lendo números de telefone, ao virar a página, está transformando sobrenome, nome, endereço etc. junto com o número de telefone.

Erik Darling
fonte
@ jpmc26 Pode ficar pior do que isso, porque se as colunas solicitadas fizerem parte de um índice, a consulta poderá ser atendida apenas olhando o índice. Se as colunas não forem indexadas, elas poderão fazer com que o registro primário seja carregado e até registros secundários para tipos de tabela / coluna não em cluster.
22420 Christopher Schultz
12

Depende da estrutura da tabela e dos índices disponíveis.

  • Caso A: Tabela comum (rowstore), sem índice ativado (order_value).

    O único plano de execução possível é ler a tabela inteira (que obviamente é muito diferente quando tem 2 vs 200 colunas, portanto alguns vs alguns milhares de bytes de largura).

  • Caso B: Tabela comum, há um índice (order_value)ou alguns outros índices que incluem essa coluna.

    Agora existe um plano melhor: varra o índice inteiro (um deles) - que é obviamente muito mais estreito que a tabela inteira, apenas alguns bytes. O que torna irrelevante se a tabela tiver 2 ou 200 colunas. Somente o índice é verificado.

  • Caso C: É uma tabela columnstore.

    Como o nome indica, a estrutura dessas tabelas é orientada por colunas, não por linhas. Não há necessidade de nenhum índice, o próprio design da tabela é adequado para a leitura de colunas inteiras.

ypercubeᵀᴹ
fonte
Meu conhecimento é um pouco verde sobre esta questão. É mais convencional (digamos, banco de dados típico do SQL Server) ter tabelas de armazenamento de linhas, correto? Por que a tabela inteira seria varrida se apenas uma coluna / campo precisasse ser retornada? Isso é inerente ao design das tabelas rowstore?
user45867
@ user45867 sim, os dados são armazenados em linhas (exceto algumas colunas muito grandes que são armazenadas fora). Quando o SQL Server lê do disco, lê em blocos inteiros, não pode ler apenas a parte que possui uma coluna.
precisa saber é o seguinte