Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Oracle 12c - o índice em uma coluna 'number' está executando mais rápido que o índice na coluna 'varchar'?


[TL;DR] Use datas para armazenar datas, números para armazenar números e strings para armazenar strings.

A Oracle armazena o NUMBER tipo de dados como 1 byte por 2 dígitos.

O Oracle armazena o CHAR tipo de dados como 1 byte por caractere ASCII (UTF-8 e outras codificações podem levar mais para caracteres em conjuntos estendidos) e preencherá a string com caracteres de espaço para que as strings tenham exatamente o mesmo comprimento.

O Oracle armazena o VARCHAR2 tipo de dados como 1 byte por caractere ASCII mais uma pequena sobrecarga (1 ou 2 bytes) para o comprimento da string.

O Oracle armazena a DATE tipo de dados como 7 bytes (2 para ano e 1 para cada mês, dia, hora, minuto, segundo).

Com base em sua pergunta anterior você parece estar armazenando year e quarter e supondo que você sempre terá anos de 4 dígitos e trimestres de 1 dígito, então:
  • NUMBER(5,0) levaria 3 bytes;
  • CHAR(5 CHARACTER) levaria 5 bytes;
  • VARCHAR2(5 CHARACTER) levaria 6 bytes; e
  • DATE levaria 7 bytes.

Portanto, considerando apenas a memória um NUMBER(5,0) seria o mais eficiente.

No entanto


Assim que você começa a fazer aritmética no ano/trimestre armazenados como números/strings, você entra em problemas de desempenho:

Por exemplo, obtendo o próximo trimestre:
  • Se quarter é um NUMBER tipo de dados, então você pode usar:CASE WHEN MOD(quarter,10) = 4 THEN quarter + 7 ELSE quarter + 1 END mas isso não funciona quando você deseja adicionar 5 quartos ou começar a subtrair quartos e, em seguida, a lógica começa a ficar muito mais complicada.
  • Se quarter é um CHAR tipo de dados, então você pode convertê-lo em um número ou uma data e usar qualquer um desses métodos (a manipulação de string provavelmente não terá bom desempenho).
  • Se quarter é uma DATE então você só precisa usar ADD_MONTHS( quarter, 3 ) .

A DATE é auto-documentado e já existe, enquanto o NUMBER O método se tornaria apenas uma função personalizada para sua aproximação de um QUARTER tipo de dados e uma vez que você implemente todas as funções de comparação e manipulação que você precisa, você terá efetivamente reescrito o DATE tipo de dados como um UDT para trimestres e essas funções terão menos desempenho do que as funções de data otimizadas.

Não use tipos de dados inadequados - apenas armazene datas como datas; números como números; e strings como string.