我有Status
列的表格,其中可能存储 CheckOut ,保持等值。现在,为了创建数据类型,我可以使用varchar
列来存储这些值,但我关注的是性能以及应用程序中的值比较,我们可能必须使用trim
函数来删除价值空间。
我应该将它存储在1号,2号,3号......还是字母中,作为' S' C' C'等,然后在应用程序中比较这些?
让我知道哪种数据类型更适合存储它:Number
vs Char
例如,如果我们想要它会影响性能:
field='S'
or
field=1
答案 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有点长,但我发现差异可以忽略不计。
所以我建议尽可能使用数字,因为整数数据的操作比字符数据快。