Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle 12c - l'index sur une colonne 'numéro' est-il plus rapide que l'index sur la colonne 'varchar'?

[TL;DR] Utilisez des dates pour stocker des dates, des nombres pour stocker des nombres et des chaînes pour stocker des chaînes.

Oracle stocke le NUMBER type de données comme 1 octet pour 2 chiffres.

Oracle stocke le CHAR type de données comme 1 octet par caractère ASCII (UTF-8 et d'autres encodages peuvent en prendre plus pour les caractères dans les ensembles étendus) et remplira à droite la chaîne avec des caractères d'espacement afin que les chaînes aient toutes exactement la même longueur.

Oracle stocke le VARCHAR2 type de données comme 1 octet par caractère ASCII plus une petite surcharge (1 ou 2 octets) pour la longueur de la chaîne.

Oracle stocke la DATE type de données comme 7 octets (2 pour l'année et 1 pour chaque mois, jour, heure, minute, seconde).

Basé sur votre question précédente vous semblez stocker year et quarter et en supposant que vous allez toujours avoir des années à 4 chiffres et des trimestres à 1 chiffre alors :

  • NUMBER(5,0) prendrait 3 octets ;
  • CHAR(5 CHARACTER) prendrait 5 octets ;
  • VARCHAR2(5 CHARACTER) prendrait 6 octets; et
  • DATE prendrait 7 octets.

Donc, ne considérer que la mémoire comme un NUMBER(5,0) serait le plus efficace.

Cependant

Dès que vous commencez à faire de l'arithmétique sur les années/trimestres stockés sous forme de nombres/chaînes, vous rencontrez des problèmes de performances :

Par exemple, obtenir le prochain trimestre :

  • Si quarter est un NUMBER type de données, vous pouvez alors utiliser :CASE WHEN MOD(quarter,10) = 4 THEN quarter + 7 ELSE quarter + 1 END mais cela ne fonctionne pas lorsque vous voulez ajouter 5 trimestres ou commencer à soustraire des trimestres, puis la logique commence à devenir beaucoup plus compliquée.
  • Si quarter est un CHAR type de données, vous pouvez le convertir en nombre ou en date et utiliser l'une ou l'autre de ces méthodes (la manipulation de chaînes n'est probablement pas performante).
  • Si quarter est une DATE alors il vous suffit d'utiliser ADD_MONTHS( quarter, 3 ) .

La DATE la méthode est auto-documentée et existe déjà alors que le NUMBER la méthode deviendrait simplement une fonction personnalisée pour votre approximation d'un QUARTER type de données et une fois que vous aurez implémenté toutes les fonctions de comparaison et de manipulation dont vous avez besoin, vous aurez effectivement réécrit le DATE type de données en tant qu'UDT pour les trimestres et ces fonctions seront moins performantes que les fonctions de date optimisées.

N'utilisez pas de types de données inappropriés - stockez simplement les dates en tant que dates ; les nombres en tant que nombres ; et les chaînes en tant que chaîne.