Alterações de esquema
- Buscar por ordem --- Se o código estiver buscando a coluna # como a maneira de obter os dados, uma alteração no esquema fará com que os números da coluna sejam reajustados. Isso atrapalha a aplicação e coisas ruins acontecem.
- Buscar por nome --- Se o código estiver buscando coluna por nome, como
foo
, e outra tabela na consulta adicionar uma coluna foo
, a maneira como isso é tratado pode causar problemas ao tentar obter a coluna correta foo
.
De qualquer maneira, uma alteração no esquema pode causar problemas com a extração dos dados.
Considere ainda se uma coluna que estava sendo usada é removida da tabela. O select * from ...
erro ainda funciona, mas ocorre um erro ao tentar extrair os dados do conjunto de resultados. Se a coluna é especificado na consulta, a consulta será erro para fora em vez dando um indiciation clara sobre o que e onde está o problema.
Sobrecarga de dados
Algumas colunas podem ter uma quantidade significativa de dados associados a elas. A seleção de volta *
puxará todos os dados. Sim, é varchar(4096)
isso que está nas 1000 linhas que você selecionou, dando a você mais 4 megabytes de dados possíveis que você não precisa, mas que são enviados de qualquer maneira.
Relacionado à alteração do esquema, esse varchar pode não existir lá quando você criou a tabela, mas agora está lá.
Falha em transmitir a intenção
Quando você seleciona voltar *
e obtém 20 colunas, mas precisa apenas de duas delas, não está transmitindo a intenção do código. Ao olhar para a consulta que é feita, select *
não se sabe quais são as partes importantes dela. Posso alterar a consulta para usar esse outro plano para torná-lo mais rápido, não incluindo essas colunas? Não sei porque a intenção do que a consulta retorna não é clara.
Vamos analisar alguns problemas do SQL que exploram essas alterações de esquema um pouco mais.
Primeiro, o banco de dados inicial: http://sqlfiddle.com/#!2/a67dd/1
DDL:
create table one (oneid int, data int, twoid int);
create table two (twoid int, other int);
insert into one values (1, 42, 2);
insert into two values (2, 43);
SQL:
select * from one join two on (one.twoid = two.twoid);
E as colunas que você receber de volta são oneid=1
, data=42
, twoid=2
, e other=43
.
Agora, o que acontece se eu adicionar uma coluna à tabela um? http://sqlfiddle.com/#!2/cd0b0/1
alter table one add column other text;
update one set other = 'foo';
E os meus resultados da mesma consulta como antes são oneid=1
, data=42
, twoid=2
, e other=foo
.
Uma mudança em uma das tabelas interrompe os valores de ae, de select *
repente, sua ligação de 'other' a um int gera um erro e você não sabe o porquê.
Se, em vez disso, sua instrução SQL foi
select
one.oneid, one.data, two.twoid, two.other
from one join two on (one.twoid = two.twoid);
A alteração na tabela um não teria interrompido seus dados. Essa consulta é executada da mesma forma antes e depois da alteração.
Indexação
Ao fazer um, select * from
você está puxando todas as linhas de todas as tabelas que correspondem às condições. Mesmo mesas com as quais você realmente não se importa. Embora isso signifique a transferência de mais dados, há outro problema de desempenho oculto na pilha.
Índices. (relacionado ao SO: como usar o índice na instrução select? )
Se você estiver retirando muitas colunas, o otimizador de plano de banco de dados pode desconsiderar o uso de um índice, porque você ainda precisará buscar todas essas colunas e levaria mais tempo para usar o índice e buscar todas as colunas na consulta do que seria apenas fazer uma verificação completa da tabela.
Se você está apenas selecionando o, digamos, sobrenome de um usuário (que você faz muito e tem um índice), o banco de dados pode fazer uma varredura apenas de índice (varredura apenas de índice postgres wiki , mysql full table vs vs full varredura de índice , varredura apenas de índice: evitando acesso à tabela ).
Há algumas otimizações sobre a leitura apenas de índices, se possível. As informações podem ser extraídas mais rapidamente em cada página de índice, porque você também extrai menos delas - não está inserindo todas as outras colunas da select *
. É possível que uma varredura apenas de índice retorne resultados da ordem de 100x mais rápido (fonte: selecione * está incorreto ).
Isso não quer dizer que uma varredura completa do índice seja ótima, ainda é uma varredura completa - mas é melhor que uma varredura de tabela completa. Quando você começa a perseguir todas as maneiras que select *
prejudicam o desempenho, continua encontrando novas.
Leitura relacionada