sql >> Database teknologi >  >> RDS >> Oracle

Oracle 12c - yder indeks på en 'nummer'-kolonne hurtigere end indeks på 'varchar'-kolonne?

[TL;DR] Brug datoer til at gemme datoer, tal til at gemme tal og strenge til at gemme strenge.

Oracle gemmer NUMBER datatype som 1 byte pr. 2 cifre.

Oracle gemmer CHAR datatype som 1 byte pr. ASCII-tegn (UTF-8 og andre kodninger kan tage mere for tegn i udvidede sæt) og vil højre-udfylde strengen med mellemrumstegn, så strengene alle har nøjagtig samme længde.

Oracle gemmer VARCHAR2 datatype som 1 byte pr. ASCII-tegn plus en lille overhead (1 eller 2 bytes) for strenglængden.

Oracle gemmer DATE datatype som 7 bytes (2 for år og 1 for hver måned, dag, time, minut, sekund).

Baseret på dit tidligere spørgsmål du ser ud til at gemme year og quarter og forudsat at du altid vil have 4-cifrede årstal og 1-cifrede kvartaler, så:

  • NUMBER(5,0) ville tage 3 bytes;
  • CHAR(5 CHARACTER) ville tage 5 bytes;
  • VARCHAR2(5 CHARACTER) ville tage 6 bytes; og
  • DATE ville tage 7 bytes.

Så kun overvejer hukommelsen et NUMBER(5,0) ville være den mest effektive.

Men

Så snart du begynder at regne på år/kvartaler gemt som tal/strenge, kommer du ind i præstationsproblemer:

For eksempel at få det næste kvartal :

  • Hvis quarter er et NUMBER datatype, så kan du bruge:CASE WHEN MOD(quarter,10) = 4 THEN quarter + 7 ELSE quarter + 1 END men dette klarer ikke, når du vil tilføje 5 kvartaler eller begynde at trække kvartaler fra, og så begynder logikken at blive meget mere kompliceret.
  • Hvis quarter er en CHAR datatype, så kan du konvertere det til et tal eller en dato og bruge en af ​​disse metoder (strengmanipulation er sandsynligvis ikke effektiv).
  • Hvis quarter er en DATE så skal du bare bruge ADD_MONTHS( quarter, 3 ) .

DATE metoden er selvdokumenterende og eksisterer allerede, mens NUMBER metode ville blot blive en brugerdefineret funktion til din tilnærmelse af en QUARTER datatype, og når du har implementeret alle de sammenlignings- og manipulationsfunktioner, du har brug for, vil du effektivt have omskrevet DATE datatype som en UDT for kvartaler, og disse funktioner vil være mindre effektive end de optimerede datofunktioner.

Brug ikke upassende datatyper - gem blot datoer som datoer; tal som tal; og strenge som streng.




  1. At finde en gennemsnitlig SQL

  2. Et-til-én-forhold med forskellige primære nøgler i EF 6.1-koden først

  3. MySql upsert og auto-increment forårsager huller

  4. Mislykket bygning af hjul til mysql-python