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 / 90439
Accepted
nateirvin
nateirvin
Asked: 2015-01-29 10:01:11 +0800 CST2015-01-29 10:01:11 +0800 CST 2015-01-29 10:01:11 +0800 CST

Que efeito a redução do tamanho de uma coluna varchar terá no arquivo de banco de dados?

  • 772

Temos várias tabelas em nosso banco de dados que possuem VARCHAR(MAX)colunas onde a VARCHAR(500)(ou algo muito menor que max) será suficiente. Naturalmente, quero limpá-los e reduzir os tamanhos para níveis mais razoáveis. O 'como' fazer isso eu entendo: minha pergunta é o que a alteração dessas colunas fará nas páginas e existentes no disco? (Há muitas informações por aí sobre o que acontece quando você aumenta uma coluna, mas é difícil encontrar informações sobre o que acontece quando você diminui uma.)

Algumas das tabelas têm uma contagem de linhas muito pequena, então não estou preocupado com o custo da alteração, mas algumas são muito grandes e estou preocupado com a possibilidade de serem reorganizadas e causar muito bloqueio/tempo de inatividade. Em termos práticos, quero apenas uma maneira de estimar uma janela de manutenção. Em geral, gostaria de entender melhor como o mecanismo de banco de dados se comporta neste caso.

Desde já, obrigado!

EDITAR:

Estou examinando 20 tabelas, embora apenas metade delas tenha contagens de linhas superiores a 1.000. O maior tem quase um milhão de linhas. O pior infrator é uma tabela com 350.000 linhas e quatro VARCHAR(MAX)colunas que podem ser reduzidas ao VARCHAR(500)nível.

sql-server sql-server-2012
  • 2 2 respostas
  • 14518 Views

2 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2015-01-29T14:15:34+08:002015-01-29T14:15:34+08:00

    Primeiras coisas primeiro: quantos dados existem na tabela? Número de linhas e tamanho da tabela?

    Segundo: você pode fazer backup e restaurar esta tabela para um servidor de teste e executar a instrução alter para ver o impacto (supondo que não seja inviável devido ao fato de a tabela ser muito grande para caber em um sistema que não seja de produção)? Sempre acho que testar em meu ambiente é mais preciso do que conselhos da internet, pois existem vários fatores que podem influenciar o resultado que podem não ser fornecidos na pergunta simplesmente por não saber que esses fatores podem afetar o resultado.

    Terceiro: aumentar o tamanho de um campo de comprimento variável é (supondo que você não exceda o limite de 8060 bytes) uma operação simples de metadados, pois nenhum dado real seria alterado para tal operação. MAS, por outro lado, reduzir o tamanho de um campo de comprimento variável, mesmo para algo que funcionará mais do que obviamente, não é uma simples alteração de metadados porque o SQL Server não sabe, antes de verificar todas as linhas , que o tamanho recém-solicitado é válido.

    Portanto: Sim, isso bloqueará a mesa por um período de tempo . Quanto tempo? Bem, aqui está o teste que acabei de fazer:

    Eu tinha, de alguns outros testes, uma tabela com um único INT NOT NULLcampo e 1 milhão de linhas. Copiei para uma nova tabela com a finalidade de fazer este teste via:

    SELECT *, CONVERT(NVARCHAR(MAX), NEWID()) AS [StringField]
    INTO dbo.ResizeTest
    FROM dbo.ClusteredUnique;
    

    Dessa forma, eu estava começando com um cenário semelhante de ter um MAXcampo (acabei de perceber que você tem VARCHARe estou usando NVARCHAR, mas isso não deve alterar o comportamento que estou vendo) que eu poderia mudar para 500. E contém dados que cabem facilmente em 500 caracteres. Isso levou alguns minutos.

    Eu então corri:

    ALTER TABLE dbo.ResizeTest ALTER COLUMN [StringField] NVARCHAR(500) NULL;
    

    E isso levou pouco mais de 11 minutos.

    Acabei de refazer o teste, desta vez descartando a [ResizeTest]tabela e alterando os dois NVARCHARs para apenas VARCHAR, apenas para ter certeza de que estou comparando maçãs com algo que pelo menos se parece com uma maçã ;-).

    A criação inicial da tabela levou 20 segundos, enquanto a ALTER TABLEde 2 minutos.

    Portanto, em termos de estimativa de tempo de inatividade, isso é realmente difícil de fazer, pois é baseado nas velocidades de E/S do disco, se alguma operação de crescimento automático precisa ou não acontecer no arquivo de dados e/ou no log de transações, etc. é provavelmente uma grande parte do motivo pelo qual meu primeiro teste levou 11 minutos para alterar e o segundo, mesmo com VARCHARmetade do tamanho dos NVARCHARdados, levou apenas 2 minutos (ou seja, os arquivos foram pré-criados naquele ponto). Mesmo assim, você deve ter em mente que meu teste está sendo executado em meu laptop, que não é o disco mais rápido, mas também tinha apenas 1 milhão de linhas de 2 colunas pequenas (22 ou mais bytes por linha).

    E já que você perguntou o que isso fará com as páginas de dados, aqui está sua resposta. Fiz um sp_spaceuseddepois de criar a tabela, depois de fazer o ALTER COLUMNe depois de fazer o ALTER TABLE dbo.ResizeTest REBUILD;. Os resultados (os números a seguir são baseados no segundo teste usando VARCHAR, não no primeiro teste usando NVARCHAR):

    After initial table creation:        526,344 KB
    After ALTER COLUMN VARCHAR(500):   1,031,688 KB  <--- !! Yikes!!
    After ALTER REBUILD:                 526,472 KB
    

    Se você está preocupado em precisar manter a operação no menor tempo possível, confira um artigo que escrevi sobre fazer exatamente isso: Restructure 100 Million Row (or more) Tables in Seconds. SRSLY! (cadastro gratuito necessário).

    • 12
  2. DForck42
    2015-01-29T13:42:23+08:002015-01-29T13:42:23+08:00

    Pelo que descobri, a execução da instrução alter não deve demorar muito, desde que a mesa não esteja bloqueada por outro processo. De acordo com gbn, é apenas uma alteração de metadados: https://stackoverflow.com/questions/7261909/is-it-bad-to-use-alter-table-to-resize-a-varchar-column-to-a-larger -Tamanho

    Além disso, quanto à forma como é armazenado, parece que o SQL Server armazenou os dados varchar em uma página de 8k até preencher uma página inteira, que neste ponto substitui por um ponteiro e os armazena como um BLOB.

    Estou assumindo que, quando você alterar o comprimento, não truncará nenhum registro. Nesse caso, no máximo, os dados que você está convertendo em varchar(500) devem ter, no máximo, 502 bytes de comprimento e não devem ter um ponteiro.

    Portanto, para encurtar a história, não deve mudar muito, desde que você não trunque nenhum dado.

    • 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