AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 253873
Accepted
J.D.
J.D.
Asked: 2019-11-22 13:33:41 +0800 CST2019-11-22 13:33:41 +0800 CST 2019-11-22 13:33:41 +0800 CST

Qual é um bom caso de uso para SELECT * no código de produção?

  • 772

Por hábito, nunca uso SELECT *em código de produção (só uso com consultas de sucata ad-hoc, normalmente ao aprender o esquema de um objeto). Mas me deparei com um caso agora em que estou tentado a usá-lo, mas me sentiria barato se o fizesse.

Meu caso de uso está dentro de um procedimento armazenado onde é criada uma tabela temporária local que deve sempre corresponder à tabela subjacente usada para criá-la, sempre que o procedimento armazenado for executado. A tabela temporária é preenchida muito mais tarde, portanto, um truque rápido para criar a tabela temporária sem ser detalhado seria SELECT * INTO #TempTable FROM RealTable WHERE 1 = 0especialmente para uma tabela com centenas de colunas.

Se o consumidor do meu procedimento armazenado for agnóstico para conjuntos de resultados dinâmicos, há algum problema comigo vendendo meus serviços para SELECT *?

sql-server sql-server-2016
  • 7 7 respostas
  • 8668 Views

7 respostas

  • Voted
  1. Best Answer
    Rusty
    2019-11-23T03:23:22+08:002019-11-23T03:23:22+08:00

    Eu geralmente abomino SELECT * no código de produção e já estive em uma situação em que seu uso levou a grandes quantidades de retrabalho posteriormente. No entanto, seu caso parece um uso justo.

    O lugar onde acho SELECT * obrigatório - e seu primo malvado "INSERT INTO tbl" sem uma lista de colunas - está em uma situação de arquivamento, onde as linhas estão sendo movidas para outra tabela que deve ter a mesma estrutura.

    INSERT INTO SalesOrderArchive  -- Note no column list
    SELECT *
      FROM SalesOrder
     WHERE OrderDate < @OneYearAgo
    
    DELETE FROM SalesOrder
     WHERE OrderDate < @OneYearAgo
    

    Se uma nova coluna for adicionada a SalesOrder no futuro, mas não a SalesOrderArchive, o INSERT falhará. O que parece ruim, mas na verdade é uma coisa muito boa! Porque a alternativa é muito pior. Se todas as colunas estivessem listadas no INSERT e no SELECT, então o INSERT seria bem sucedido, assim como o DELETE a seguir (que é efetivamente "DELETE *"). O código de produção bem-sucedido não recebe nenhuma atenção e pode levar muito tempo até que alguém perceba que a nova coluna não está sendo arquivada, mas totalmente excluída silenciosamente.

    • 57
  2. David Browne - Microsoft
    2019-11-22T17:31:26+08:002019-11-22T17:31:26+08:00

    Qual é um bom uso de select * na produção?

    IMO apenas coisas assim:

    por exemplo

    create table #foo(a int, b int, c int, d int)
    ...
    select * from #foo
    

    ou

    with q as
    (
      select a, b, c
      from ...
    )
    select *
    from q
    

    ou seja, quando o *está vinculado a uma lista de colunas explícita que é declarada no mesmo lote e é usado apenas para evitar repetir a lista de colunas várias vezes.

    Quando o *se refere a uma tabela ou visualização, existem algumas complexidades desagradáveis ​​sobre metadados em cache, por exemplo, aqui . E isso realmente não economiza a digitação, pois o SSMS permitirá que você arraste e solte a lista de colunas completa.

    • 37
  3. user195591
    2019-11-23T03:47:59+08:002019-11-23T03:47:59+08:00

    Um uso válido de SELECT *ocorre quando introduzido por EXISTS.

    WHERE EXISTS (SELECT * FROM ...
    

    Como todos os usos de SELECT *, isso tem o efeito colateral indesejado (e desnecessário aqui) de impedir que WITH SCHEMABINDINGseja adicionado se o código estiver dentro, por exemplo, de uma função.

    Perguntas e respostas relacionadas: EXISTS (SELECT 1 ...) vs EXISTS (SELECT * ...) Um ou outro?

    Veja também:

    • Maus hábitos para chutar: usando SELECT * / omitindo a lista de colunas por Aaron Bertrand
    • Quando Selecione * Não Importa por Erik Darling.
    • 23
  4. S3S
    2019-11-22T14:28:59+08:002019-11-22T14:28:59+08:00

    Qual é um bom uso de select * na produção?

    Realmente, não há. No desenvolvimento das maneiras que você mencionou (selecione top n *), faz sentido, mas desenvolve maus hábitos e pode levar a problemas.

    Você tocou no ponto principal sobre por que você não deve usá-lo, e essa é a estrutura da tabela real que pode mudar. Criar uma tabela temporária como você mencionou é tudo de bom, mas onde você pode chegar é mais tarde em seu proc, depois de preencher a tabela temporária com alguns INSERTcomandos, você retorna o conjunto de resultados com SELECT *. Agora, seu aplicativo final recuperaria colunas que não são esperadas.

    Você pode usar SELECT ... INTO #TEMP FROM ...para criar a tabela temporária em tempo real também. É meio difícil saber qual é o melhor para sua situação.

    A maioria dos outros problemas SELECT *não parecem importar para o seu caso de uso

    • Criando uma visão (pode quebrar quando a tabela muda)
    • Problemas de vinculação
    • Varredura de tabela (já que você realmente deseja todas as colunas)
    • Recuperando colunas desnecessárias (já que você parece querer todas elas novamente) e sua posição ordinal
    • 7
  5. Kevin
    2019-11-23T09:51:38+08:002019-11-23T09:51:38+08:00

    Vou ser ousado e dizer: Existem casos de uso para SELECT * no código de produção. Sempre que você puder dizer "Quero que qualquer alteração na tabela seja refletida imediatamente em uma alteração na saída do meu resultado" é um caso para fazê-lo.

    Deixe-me dar alguns exemplos:

    Caso de uso 1 - Faça uma exibição que espelhe a tabela principal, exceto que filtra os dados corporativos confidenciais.

    Nesse caso, você deseja que a exibição SELECT *. A saída deve ser um reflexo da tabela principal. Fazer com que o layout de saída corresponda ao layout da tabela é um recurso, não um bug.

    ...

    Caso de uso 2 - Faça um proc armazenado que copie alguns registros que você está prestes a atualizar em uma tabela de retenção temporária, caso o processo apresente problemas (é meio esquisito).

    Nesse caso, ter uma saída que não corresponda à tabela em si é terrível - significa que você pode não conseguir usar os dados na tabela de retenção temporária para voltar ao ponto de partida.

    • 7
  6. greg
    2019-11-23T07:13:49+08:002019-11-23T07:13:49+08:00

    Minha resposta à sua pergunta é "A maioria/muitos casos de uso"

    Seus casos de uso destacam por que * não é horrível. Seu esquema será alterado. Por que se preparar para tocar em cada SP porque você precisa adicionar um campo?

    Se você estiver adicionando um campo, por que minha interface do usuário se importaria? Se você estiver excluindo um campo, não importa se você usa * ou um CSV, você está introduzindo uma alteração importante.

    "Se o consumidor do meu procedimento armazenado for agnóstico para conjuntos de resultados dinâmicos, ..."

    Aqui está o verdadeiro problema com o uso select *. Se o seu consumidor for mal escrito, você poderá ter problemas. Por exemplo, se você estiver formatando Fields[13] como uma data...

    Alguns casos em que eu evitaria selecionar *:

    Mitigação de latência - Meu consumidor está distante e precisa apenas de um subconjunto relativamente pequeno de campos na(s) tabela(s)

    Joins - Consulta complexa envolvendo várias tabelas. O consumidor provavelmente não precisa de todos os campos de todas as tabelas. Na verdade, existem colunas de chave duplicadas que provavelmente devem ser omitidas.

    Eu sei que meus consumidores escrevem código ruim - Se você estiver desenvolvendo uma API pública, suponho que seja possível que você queira honrar o OpenClose e criar um novo método de API toda vez que o conjunto de campos for alterado. Para mim, isso parece uma abordagem ruim para o referido problema ...

    Como em qualquer coisa com programação, há hora e lugar. Há sempre o conjunto da torre de marfim. Ouça seus pensamentos com uma mente aberta. Então decida-se.

    • 1
  7. Andrew Hill
    2020-01-03T19:57:56+08:002020-01-03T19:57:56+08:00

    depende do mecanismo de falha que você preferir.

    Se, quando uma nova coluna for adicionada, ela sempre puder ser ignorada com segurança (por exemplo: selecione primeiro nome, sobrenome de clientes onde id=@x), então nunca use select * - quanto mais colunas você tocar, menor a chance de um índice útil pode ser encontrado/criado.

    Se quando uma nova coluna for adicionada, o descarte silencioso dela for ruim (qualquer tipo de replicação de dados), então use uma seleção não especificada (insira em archiveTable select * from theTable where isOld=true) A falha de código aqui não é um bug, é é um recurso - especialmente no caso em que você controla o banco de dados e o código lendo a tabela.

    Reverter os mecanismos de falha aqui é ruim - você não quer que sua pesquisa de nome falhe se adicionar uma nova cor favorita à pessoa.

    você não quer ignorar o arquivamento da cor favorita da pessoa se a coluna foi adicionada depois que você escreveu o código de arquivamento.

    Uma observação sobre junções - o sql server pulará a leitura de quaisquer colunas não usadas posteriormente

    select firtname,email from (select * from profile where isArchived=false)p join (select * from emailaddresses where mostRecentSend < ago(6days))e on p.id=e.profileId
    

    não toca em nada além das colunas firstname, id e email.

    • 0

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve