sql - upper - Oracle 12c-L'indice su una colonna 'numero' si sta dimostrando più veloce dell'indice sulla colonna 'varchar'?



using index pl sql (1)

[TL; DR] Utilizza le date per memorizzare date, numeri per memorizzare numeri e stringhe per memorizzare le stringhe.

Che ne dici dell'utilizzo delle risorse?

Oracle memorizza il tipo di dati NUMBER come 1 byte per 2 cifre.

Oracle memorizza il tipo di dati CHAR come 1 byte per carattere ASCII (UTF-8 e altre codifiche potrebbero richiedere più caratteri per i set estesi) e riempirà a destra la stringa con caratteri di spazio in modo che le stringhe abbiano esattamente la stessa lunghezza.

Oracle memorizza il tipo di dati VARCHAR2 come 1 byte per carattere ASCII più un piccolo overhead (1 o 2 byte) per la lunghezza della stringa.

Oracle memorizza il tipo di dati DATE come 7 byte (2 per anno e 1 per ogni mese, giorno, ora, minuto, secondo).

In base alla tua domanda precedente , sembra che tu stia memorizzando l' year e il quarter e supponendo che avrai sempre anni a 4 cifre e quarti a 1 cifra:

  • NUMBER(5,0) richiederebbe 3 byte;
  • CHAR(5 CHARACTER) richiederebbe 5 byte;
  • VARCHAR2(5 CHARACTER) richiederebbe 6 byte; e
  • DATE richiederebbe 7 byte.

Quindi solo considerando la memoria un NUMBER(5,0) sarebbe il più efficiente.

però

Non appena inizi a fare operazioni aritmetiche su un anno / quarti memorizzati come numeri / stringhe, hai problemi di rendimento:

Ad esempio, ottenendo il trimestre successivo:

  • Se quarter è un tipo di dati NUMBER è possibile utilizzare: CASE WHEN MOD(quarter,10) = 4 THEN quarter + 7 ELSE quarter + 1 END ma questo non viene gestito quando si desidera aggiungere 5 trimestri o iniziare a sottrarre i trimestri e quindi la logica inizia a diventare molto più complicata.
  • Se quarter è un tipo di dati CHAR è possibile convertirlo in un numero o in una data e utilizzare uno di questi metodi (la manipolazione delle stringhe probabilmente non è performante).
  • Se quarter è un DATE devi solo utilizzare ADD_MONTHS( quarter, 3 ) .

Il metodo DATE è auto-documentante e già esiste mentre il metodo NUMBER diventerebbe solo una funzione personalizzata per l'approssimazione di un tipo di dati QUARTER e una volta implementate tutte le funzioni di confronto e manipolazione necessarie, avrai effettivamente riscritto il tipo di dati DATE come un UDT per quarti e quelle funzioni saranno meno perfomant delle funzioni di data ottimizzata.

Non utilizzare tipi di dati inappropriati: è sufficiente memorizzare le date come date; numeri come numeri; e stringhe come stringa.

Diciamo che ho una tabella in Oracle 12c con colonne:

create table t1 (
a number (5,0),
b varchar (5,0)
d ...
e ...
);

Quindi inserisco 100.000.000 di record in entrambe le colonne che hanno gli stessi valori - ad es

20151 and '20152' ... (for a first record)
20152 and '20152' ... (for a second record)
20153 and '20153' ... (for a third record)
...

Quindi aggiungo l'indice 1 sulla colonna 'a' e l'indice 2 sulla colonna 'b'.

La domanda è: la query deve essere altrettanto veloce quando si esegue contro la colonna 'a' come sulla colonna 'b' (ad esempio, una query di join con un'altra tabella basata su una colonna 'a' o basata su una colonna 'b' o una clausola WHERE su uno dei due colonne)?

Inoltre, utilizzare l'indice su una colonna " varchar ", utilizzare più CPU rispetto all'utilizzo dell'indice su una colonna "numero"?

Grazie.





numbers