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 / 218479
Accepted
gotqn
gotqn
Asked: 2018-09-25 22:52:26 +0800 CST2018-09-25 22:52:26 +0800 CST 2018-09-25 22:52:26 +0800 CST

Quando `nvarchar/nchar` será usado com o SQL Server 2019?

  • 772

Com o SQL Server 2019, a Microsoft apresenta suporte a UTF-8CHAR e VARCHARtipos de dados e diz:

Esse recurso pode proporcionar economias de armazenamento significativas, dependendo do conjunto de caracteres em uso. Por exemplo, alterar um tipo de dados de coluna existente com strings ASCII de NCHAR(10) para CHAR(10) usando um agrupamento habilitado para UTF-8 se traduz em quase 50% de redução nos requisitos de armazenamento. Essa redução ocorre porque NCHAR(10) requer 22 bytes para armazenamento, enquanto CHAR(10) requer 12 bytes para a mesma string Unicode.

O UTF-8 parece suportar todos os scripts, então basicamente podemos começar a armazenar dados Unicode em varchare charcolunas. E como é dito na documentação, isso pode reduzir o tamanho das tabelas e índices, e a partir daí podemos obter um desempenho ainda melhor, pois uma quantidade menor de dados é lida.

Eu estou querendo saber se isso significa que podemos parar de usar nvarchare ncharcolunas que implementam UTF-16?

Alguém pode apontar um cenário e motivo, para não usar os tipos de dados char com UTFcodificação e continuar usando os n-chars?

sql-server datatypes
  • 2 2 respostas
  • 2617 Views

2 respostas

  • Voted
  1. Paul White
    2018-09-27T23:00:14+08:002018-09-27T23:00:14+08:00

    O suporte a UTF-8 oferece um novo conjunto de opções. Potencial economia de espaço (sem compactação de linha ou página ) é uma consideração, mas a escolha do tipo e codificação provavelmente deve ser feita principalmente com base nos requisitos reais para comparação, classificação, importação de dados e exportação .

    Você pode precisar alterar mais do que pensa, pois, por exemplo, um nchar(1)tipo fornece dois bytes de armazenamento. Isso é suficiente para armazenar qualquer caractere em BMP (pontos de código 000000 a 00FFFF). Alguns dos caracteres nesse intervalo seriam codificados com apenas 1 byte em UTF-8, enquanto outros exigiriam 2 ou até 3 bytes (consulte este gráfico de comparação para obter mais detalhes). Portanto, garantir a cobertura do mesmo conjunto de caracteres em UTF-8 exigiria char(3).

    Por exemplo:

    DECLARE @T AS table 
    (
        n integer PRIMARY KEY,
        UTF16 nchar(1) COLLATE Latin1_General_CI_AS,
        UTF8 char(1) COLLATE Latin1_General_100_CI_AS_SC_UTF8
    );
    
    INSERT @T (n, UTF16, UTF8)
    SELECT 911, NCHAR(911), NCHAR(911);
    

    dá o erro familiar:

    Msg 8152, Level 16, State 30, Line xxx
    String ou dados binários seriam truncados.

    Ou se o sinalizador de rastreamento 460 estiver ativo:

    Msg 2628, Level 16, State 1, Line xxx
    String ou dados binários seriam truncados na tabela '@T', coluna 'UTF8'. Valor truncado: ' '.

    Expandir a coluna UTF8 para char(2)ou varchar(2)resolve o erro para NCHAR(911):

    DECLARE @T AS table 
    (
        n integer PRIMARY KEY,
        UTF16 nchar(1) COLLATE Latin1_General_CI_AS,
        UTF8 varchar(2) COLLATE Latin1_General_100_CI_AS_SC_UTF8
    );
    
    INSERT @T (n, UTF16, UTF8)
    SELECT 911, NCHAR(911), NCHAR(911);
    

    No entanto, se fosse, por exemplo NCHAR(8364), , você precisaria expandir ainda mais a coluna, para char(3)ou varchar(3).

    Observe também que todos os agrupamentos UTF-8 usam caracteres suplementares, portanto , não funcionarão com replicação.

    Além de qualquer outra coisa, o suporte a UTF-8 está apenas em pré-visualização no momento, portanto, não está disponível para uso em produção.

    • 13
  2. Best Answer
    Solomon Rutzky
    2018-10-03T11:50:38+08:002018-10-03T11:50:38+08:00

    isso pode reduzir o tamanho das tabelas e índices (ênfase adicionada)

    A redução de tamanho só é possível se a maioria dos caracteres for essencialmente [space], 0 - 9, A - Z, a - z, e alguma pontuação básica. Fora desse conjunto específico de caracteres (em termos de uso prático, valores ASCII padrão de 32 a 126), você será, na melhor das hipóteses, igual em tamanho a NVARCHAR/ UTF-16 ou, em muitos casos, maior.

    Estou planejando migrar os dados, pois acredito que ler menos dados levará a um melhor desempenho do sistema.

    Tome cuidado. UTF-8 não é um switch mágico de "consertar tudo". Todas as outras coisas sendo iguais, sim, ler menos melhora o desempenho. Mas aqui "todas as outras coisas" não são iguais. Mesmo ao armazenar apenas caracteres ASCII padrão (ou seja: todos os caracteres são de 1 byte, portanto, exigindo metade do espaço em comparação com o armazenamento em NVARCHAR), há uma pequena penalidade de desempenho ao usar UTF-8. Acredito que o problema se deve ao fato de o UTF-8 ser uma codificação de comprimento variável, o que significa que cada byte deve ser interpretado conforme é lido para saber se é um caractere completo ou se o próximo byte faz parte dele. Isso significa que todas as operações de string precisam começar no início e prosseguir byte a byte. Por outro lado,NVARCHAR/ UTF-16 é sempre de 2 bytes (mesmo Caracteres Suplementares são compostos por dois Pontos de Código de 2 bytes), então tudo pode ser lido em pedaços de 2 bytes.

    Em meus testes, mesmo com apenas caracteres ASCII padrão, armazenar os dados como UTF-8 não proporcionou economia de tempo decorrido, mas foi definitivamente pior para o tempo de CPU. E isso foi sem compactação de dados, então pelo menos havia menos espaço em disco usado. Mas, ao usar compactação, o espaço necessário para UTF-8 era apenas 1% - 1,5% menor. Tão eficazmente sem economia de espaço ainda maior tempo de CPU para UTF-8.

    As coisas ficam mais complicadas ao usar NVARCHAR(MAX), pois a compactação Unicode não funciona com esse tipo de dados, mesmo que o valor seja pequeno o suficiente para ser armazenado em linha. Mas, se os dados forem pequenos o suficiente, eles ainda devem se beneficiar da compactação de linha ou página (nesse caso, ele se torna mais rápido que o UTF-8). No entanto, os dados fora da linha não podem usar nenhuma compactação. Ainda assim, tornar a tabela um Índice Columnstore Clusterizado reduz bastante o tamanho de NVARCHAR(MAX)(mesmo que ainda seja um pouco maior que UTF-8 ao usar o Índice Columnstore Clusterizado).

    Alguém pode apontar um cenário e motivo, para não usar os tipos de dados char com codificação UTF

    Definitivamente. Na verdade, eu realmente não encontro uma razão convincente para usá-lo na maioria dos casos. O único cenário que realmente se beneficia do UTF-8 é:

    1. Os dados são principalmente ASCII padrão (valores 0 - 127)
    2. Ele precisa ser Unicode porque pode precisar armazenar um intervalo maior de caracteres do que está disponível em qualquer página de código de 8 bits (ou seja, VARCHAR)
    3. A maioria dos dados é armazenada fora da linha (portanto, a compactação de página nem funciona)
    4. Você tem dados suficientes que precisa/quer reduzir o tamanho por motivos que não são de desempenho de consulta (por exemplo, reduzir o tamanho do backup, reduzir o tempo necessário para fazer backup/restauração etc.)
    5. Você não pode usar o Índice Columnstore Clusterizado (talvez o uso da tabela piore o desempenho neste caso?)

    Meus testes mostram que em quase todos os casos, o NVARCHAR foi mais rápido, especialmente quando havia mais dados. Na verdade, 21 mil linhas com uma média de 5 mil caracteres por linha exigiam 165 MB para UTF-8 e 236 MB para NVARCHARnão compactados. E, no entanto, NVARCHARfoi 2x mais rápido no tempo decorrido e pelo menos 2x mais rápido (às vezes mais) no tempo de CPU. Ainda assim, ele ocupava 71 MB a mais no disco.

    Fora isso, eu ainda não recomendaria usar UTF-8, pelo menos a partir do CTP 2, devido a uma variedade de bugs que encontrei nesse recurso.

    Para uma análise detalhada desse novo recurso, incluindo uma explicação das diferenças entre UTF-16 e UTF-8 e uma lista desses bugs, consulte minha postagem:

    Suporte nativo a UTF-8 no SQL Server 2019: Salvador ou Falso Profeta?

    • 7

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