Oracle单值字段数据类型

时间:2016-03-05 08:34:56

标签: database oracle performance

我有Status列的表格,其中可能存储 CheckOut 保持等值。现在,为了创建数据类型,我可以使用varchar列来存储这些值,但我关注的是性能以及应用程序中的值比较,我们可能必须使用trim函数来删除价值空间。

我应该将它存储在1号,2号,3号......还是字母中,作为' S' C' C'等,然后在应用程序中比较这些?

让我知道哪种数据类型更适合存储它:Number vs Char

例如,如果我们想要它会影响性能:

field='S'
or
field=1

2 个答案:

答案 0 :(得分:2)

对于那些对某些指标感兴趣的人,这里有一系列SQL语句来测试一个字符列(VARCHAR2(1))和一个1位数列(NUMBER(1))上的查询。

测试设置 - 创建一个100,000,000行表,其中包含字符状态列和数字状态列。运行简单查询以使用字符状态过滤器对行进行计数,并将其时间与使用数字状态运行类似查询进行比较。

执行摘要 - 差异难以察觉。

SQL> create table some_100_rows
  2  as
  3  select rownum as rnum
  4  from dual
  5  connect by level <= 100;

Table created.

SQL> create table some_1000000_rows
  2  as
  3  select ROWNUM as id
  4       , cast(case when mod(rownum, 2) = 0 then 'S' else 'C' end as varchar2(1)) as varchar_status
  5       , cast(case when mod(rownum, 2) = 0 then 1 else 2 end as number(1)) as num_status
  6    from dual
  7   connect by level <= 1000000
  8   ;

Table created.

Elapsed: 00:00:01.46

(我保持数据和分布简单,以便字符搜索和数字搜索做同样的事情,时间上的差异应该仅仅归因于数据类型。)

SQL>  create table test_varchar_vs_number -- a table of 100,000,000 rows
  2   as
  3   select t1.*
  4   from some_1000000_rows t1
  5        cross join
  6        some_100_rows t2
  7  ;

Table created.

Elapsed: 00:00:37.96

SQL> select count(*)
  2    from test_varchar_vs_number
  3  ;

  COUNT(*)
----------
 100000000

Elapsed: 00:00:10.54

请注意,只计算表只需要大约10秒钟。

这里的内容是什么:

SQL>  select *
  2   from test_varchar_vs_number
  3   where rownum < 11;

        ID VARCHAR_STATUS NUM_STATUS
---------- -------------- ----------
         1              C          2
         2              S          1
         3              C          2
         4              S          1
         5              C          2
         6              S          1
         7              C          2
         8              S          1
         9              C          2
        10              S          1

10 rows selected.

Elapsed: 00:00:00.04

运行选择以使用&#34; S&#34;计算行数。在VARCHAR_STATUS列中。重复几次以获得稳定的指标。

SQL> select count(*)
  2    from test_varchar_vs_number
  3   where varchar_status = 'S'
  4   ;

  COUNT(*)
----------
  50000000

**Elapsed: 00:00:11.82**

SQL> select count(*)
  2    from test_varchar_vs_number
  3   where varchar_status = 'S'
  4   ;

  COUNT(*)
----------
  50000000

**Elapsed: 00:00:11.05**

SQL> select count(*)
  2    from test_varchar_vs_number
  3   where varchar_status = 'S'
  4   ;

  COUNT(*)
----------
  50000000

**Elapsed: 00:00:11.37**

所以只需11秒就可以算上50,000,000&#34; S&#34;行。

现在尝试使用NUMBER_STATUS列中的1行进行相同的操作:

SQL> select count(*)
  2    from test_varchar_vs_number
  3   where num_status = 1;

  COUNT(*)
----------
  50000000

**Elapsed: 00:00:11.04**

SQL> select count(*)
  2    from test_varchar_vs_number
  3   where num_status = 1;

  COUNT(*)
----------
  50000000

**Elapsed: 00:00:10.79**

SQL> select count(*)
  2    from test_varchar_vs_number
  3   where num_status = 1;

  COUNT(*)
----------
  50000000

**Elapsed: 00:00:10.59**

所以,差异可以忽略不计。 (最小搜索时间:11.05秒vs最小号码搜索时间10.59秒。)

编辑: 对于那些对低级细节感兴趣的人,这里是通过tkprof的10046跟踪的统计数据。这是从上面单独运行,所以不要期望时间完全匹配。 (请记住,查询的所有3次运行的总时间。)

select count(*)
  from test_varchar_vs_number
 where num_status = 1

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          0          0           0
Fetch        6     11.85      34.30     621984     622005          0           3
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       12     11.85      34.30     621984     622005          0           3

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 110  
Number of plan statistics captured: 3

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         1          1          1  SORT AGGREGATE (cr=207335 pr=207328 pw=0 time=11434679 us)
  50000000   50000000   50000000   TABLE ACCESS FULL TEST_VARCHAR_VS_NUMBER (cr=207335 pr=207328 pw=0 time=10113986 us cost=56992 size=150000000 card=50000000)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       6        0.00          0.00
  reliable message                                1        0.00          0.00
  enq: KO - fast object checkpoint                1        0.13          0.13
  direct path read                             4835        0.29         22.04
  SQL*Net message from client                     6        0.01          0.04
********************************************************************************


select count(*)
  from test_varchar_vs_number
 where varchar_status = 'S'

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          0          0           0
Fetch        6     11.20      33.43     621984     622005          0           3
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       12     11.20      33.43     621984     622005          0           3

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 110  
Number of plan statistics captured: 3

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         1          1          1  SORT AGGREGATE (cr=207335 pr=207328 pw=0 time=11146155 us)
  50000000   50000000   50000000   TABLE ACCESS FULL TEST_VARCHAR_VS_NUMBER (cr=207335 pr=207328 pw=0 time=9700296 us cost=56940 size=100000000 card=50000000)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       6        0.00          0.00
  reliable message                                1        0.00          0.00
  enq: KO - fast object checkpoint                1        0.21          0.21
  direct path read                             4873        0.25         22.12
  SQL*Net message from client                     6        0.03          0.05
********************************************************************************

答案 1 :(得分:0)

  

Oracle中的NUMBER数据类型存储为BCD(二进制编码   十进制)实际上是一个字符串类型。所以比较一下   和varchar / char基本相同。唯一的区别是   字符数据类型通过NLS层,所以需要一个   teensy有点长,但我发现差异可以忽略不计。

所以我建议尽可能使用数字,因为整数数据的操作比字符数据快。

Detail discussion here