Oracle 12c - is index on a 'number' column performing faster than index on 'varchar' column?

丶灬走出姿态 提交于 2019-12-08 13:29:12

问题


Let's say I have a table in Oracle 12c with columns:

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

Then I insert 100,000,000 records in both columns which have the same values - e.g.

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

Then I add index 1 on column 'a' and index 2 on column 'b'.

Question is - would the query perform equally fast when executing against column 'a' as on column 'b' (e.g. join query with other table based on a column 'a' or based on a column 'b' or WHERE clause on either of columns)?

Also - would using index on a 'varchar' column - use more CPU than using index on a 'number' column?

Thanks.


回答1:


[TL;DR] Use dates to store dates, numbers to store numbers and strings to store strings.

How about resource usage?

Oracle stores the NUMBER data type as 1 byte per 2 digits.

Oracle stores the CHAR data type as 1 byte per ASCII character (UTF-8 and other encodings may take more for characters in extended sets) and will right-pad the string with space characters so the strings are all exactly the same length.

Oracle stores the VARCHAR2 data type as 1 byte per ASCII character plus a small overhead (1 or 2 bytes) for the string length.

Oracle stores the DATE data type as 7 bytes (2 for year and 1 for each of month, day, hour, minute, second).

Based on your previous question you appear to be storing year and quarter and assuming that you are always going to have 4-digit years and 1-digit quarters then:

  • NUMBER(5,0) would take 3 bytes;
  • CHAR(5 CHARACTER) would take 5 bytes;
  • VARCHAR2(5 CHARACTER) would take 6 bytes; and
  • DATE would take 7 bytes.

So only considering memory a NUMBER(5,0) would be the most efficient.

However

As soon as you start to do arithmetic on year/quarters stored as numbers/strings then you get into performance issues:

For example, getting the next quarter :

  • If quarter is a NUMBER data type then you could use: CASE WHEN MOD(quarter,10) = 4 THEN quarter + 7 ELSE quarter + 1 END but this doesn't handle when you want to add 5 quarters or start subtracting quarters and then the logic starts to get much more complicated.
  • If quarter is a CHAR data type then you could convert it to a number or a date and use either of those methods (string manipulation is not likely to be performant).
  • If quarter is a DATE then you just need to use ADD_MONTHS( quarter, 3 ).

The DATE method is self-documenting and already exists whereas the NUMBER method would just become a custom function for your approximation of a QUARTER data type and once you implement all the comparison and manipulation functions you need you will have effectively rewritten the DATE data type as a UDT for quarters and those functions will be less perfomant than the optimised date functions.

Don't use inappropriate data types - just store dates as dates; numbers as numbers; and strings as string.



来源:https://stackoverflow.com/questions/47043564/oracle-12c-how-much-does-it-really-affect-varchar-column-comparing-to-number-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!