Aproveitei um tema recorrente nas minhas aulas de Banco de Dados no SENAC para desenvolver este artigo. Frequentemente, os alunos me perguntam por que recomendo o uso do tipo de dado VARCHAR2 para colunas que armazenam textos de tamanho variável, em vez do tipo CHAR. Essa dúvida é comum e pode parecer simples à primeira vista, mas a escolha entre esses dois tipos pode impactar diretamente o desempenho do banco de dados.
O CHAR sempre armazena o número fixo de caracteres que for definido, completando os espaços que sobraram. Já o VARCHAR2 armazenada o conteúdo inserido, ocupando apenas o espaço necessário para o mesmo.
Imagine uma situação em que uma coluna é definida como CHAR(200) para armazenar nomes. Ao inserir o nome 'Paulo', que tem 5 letras, o Oracle armazenará esse valor com 195 espaços em branco à direita para completar os 200 caracteres definidos no tipo CHAR.
Ou seja, mesmo que o conteúdo útil tenha apenas 5 caracteres, o espaço armazenado será equivalente a 200 caracteres.
- Aumento de I/O;
- Desperdício de espaço em disco e cache;
- Maior lentidão em consultas;
Para exemplificar essa situação, será feita uma simulação no Oracle, criando duas tabelas de teste, uma com coluna do tipo CHAR(100), outra do tipo VARCHAR2(100) e serão inseridos alguns milhões de registros para podermos simular.
SQL> SQL> CREATE TABLE teste_char ( nome CHAR(100) ); 2 3 Table created. SQL> SQL> CREATE TABLE teste_varchar ( nome VARCHAR2(100) ); 2 3 Table created. SQL> SQL> BEGIN FOR a IN 1 .. 10 LOOP FOR i IN 1 .. 200000 LOOP INSERT INTO teste_char VALUES ('João'); INSERT INTO teste_varchar VALUES ('João'); END LOOP; COMMIT; END LOOP; END; / 2 3 4 5 6 7 8 9 10 PL/SQL procedure successfully completed. SQL> SQL>
A primeira verificação será para consultar o espaço ocupado por cada uma das tabelas após a inserção dos dados.
SQL> SQL> col segment_name for a30 SELECT segment_name, bytes/1024/1024 AS tamanho_mb FROM user_segments WHERE segment_name IN ('TESTE_CHAR', 'TESTE_VARCHAR');SQL> 2 3 SEGMENT_NAME TAMANHO_MB ------------------------------ ---------- TESTE_CHAR 232 TESTE_VARCHAR 33 SQL>
Aqui podemos notar que para armazenar a mesma quantidade de registros a tabela com o campo CHAR ocupou 232MB, enquanto a com VARCHAR2 apenas 33MB.
Agora vamos verificar como fica a performance ao realizar uma consulta em cada uma das tabelas.
SQL> SQL> SET TIMING ON SQL> SELECT COUNT(*) FROM teste_char WHERE nome = 'João'; COUNT(*) ---------- 2000000 Elapsed: 00:00:01.13 SQL> SQL> SELECT COUNT(*) FROM teste_varchar WHERE nome = 'João'; COUNT(*) ---------- 2000000 Elapsed: 00:00:00.22 SQL>
Enquanto a consulta na tabela com CHAR levou 1,13 segundos a consulta na tabela com VARCHAR2 levou 0,22 segundos. A diferença de tempo ocorre devido ao CHAR preencher os espaços (padding).
Então, quando usar o CHAR ?
Apenas quando o conteúdo tem tamanho fixo garantido e o uso de espaço previsível for um requisito, como:
- Códigos ISO de país (ex: 'BR', 'US')
- Flags (Y / N)
- Dados que serão processados em massa com alinhamento binário (raro)
Comentários
Postar um comentário