Oracle 12c - “数字”列的索引是否比“varchar”列上的索引执行速度更快?

时间:2017-11-01 13:21:25

标签: sql oracle indexing numbers

假设我在Oracle 12c中有一个表格,其中包含以下列:

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

然后我在两个具有相同值的列中插入100,000,000条记录 - 例如

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

然后我在列'a'上添加索引1,在列'b'.上添加索引2

问题是 - 在列'a'上执行列'b'时查询的执行速度是否相同(例如join查询基于列'a'的其他表或基于任一列上的列'b'WHERE子句?)

另外 - 在'varchar'列上使用索引 - 使用比在'number'列上使用索引更多的CPU?

感谢。

1 个答案:

答案 0 :(得分:1)

[TL; DR] 使用日期存储日期,存储数字的数字和存储字符串的字符串。

  

资源使用情况如何?

Oracle将NUMBER数据类型存储为每2位1个字节。

Oracle将CHAR数据类型存储为每个ASCII字符1个字节(UTF-8和其他编码可能需要更多扩展集中的字符),并将字符串用空格字符填充,以便字符串全部完全相同的长度。

Oracle将VARCHAR2数据类型存储为每个ASCII字符1个字节加上字符串长度的小开销(1或2个字节)。

Oracle将DATE数据类型存储为7 bytes(年份为2,月,日,时,分,秒各为1)。

根据your previous question,您似乎正在存储yearquarter,并假设您总是会有4位数年份和1位数季度:

  • NUMBER(5,0)需要3个字节;
  • CHAR(5 CHARACTER)需要5个字节;
  • VARCHAR2(5 CHARACTER)需要6个字节;和
  • DATE需要7个字节。

因此,只考虑记忆NUMBER(5,0)将是最有效的。

然而

一旦你开始对存储为数字/字符串的年/季度进行算术运算,你就会遇到性能问题:

例如,下一季度:

  • 如果quarterNUMBER数据类型,那么您可以使用:CASE WHEN MOD(quarter,10) = 4 THEN quarter + 7 ELSE quarter + 1 END但是当您想要添加5个季度或开始减去季度时,这不会处理逻辑开始变得更加复杂。
  • 如果quarterCHAR数据类型,那么您可以将其转换为数字或日期并使用其中任何一种方法(字符串操作不太可能具有高效性)。
  • 如果quarterDATE,那么您只需要使用ADD_MONTHS( quarter, 3 )

DATE方法是自我记录的并且已经存在,而NUMBER方法只是成为QUARTER数据类型近似的自定义函数,并且一旦实现所有比较您需要的操作函数将有效地将DATE数据类型重写为四分之一的UDT,并且这些函数的性能将不如优化的日期函数。

不要使用不合适的数据类型 - 只将日期存储为日期;数字作为数字;和字符串作为字符串。