目前我们有一个只有整数值声明为NUMBER的列。同时它是我们的(唯一)索引。我想知道如果你将索引声明为INTEGER会对性能产生影响吗?或者Oracle是否足够聪明才能看到它是一个整数?非常感谢你。
答案 0 :(得分:4)
不,它不会。
使用Florin的测试表,您可以设置一个小测试工具,每个查询运行数百次并平均经过的时间。就我而言,我分别运行了500次查询。
有时候,NUMBER
版本的运行速度会稍微快一点(1.232百分之一秒对1.284百分之一秒)。
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_start_time number;
3 l_end_time number;
4 l_cnt number;
5 l_iterations number := 500;
6 begin
7 l_start_time := dbms_utility.get_time();
8 for i in 1 .. l_iterations
9 loop
10 select count(*)
11 into l_cnt
12 from fg_test;
13 end loop;
14 l_end_time := dbms_utility.get_time();
15 dbms_output.put_line( 'Average elapsed (number) = ' ||
16 (l_end_time - l_start_time)/l_iterations ||
17 ' hundredths of a second.' );
18 l_start_time := dbms_utility.get_time();
19 for i in 1 .. l_iterations
20 loop
21 select count(*)
22 into l_cnt
23 from fg_test1;
24 end loop;
25 l_end_time := dbms_utility.get_time();
26 dbms_output.put_line( 'Average elapsed (integer) = ' ||
27 (l_end_time - l_start_time)/l_iterations ||
28 ' hundredths of a second.' );
29* end;
30 /
Average elapsed (number) = 1.232 hundredths of a second.
Average elapsed (integer) = 1.284 hundredths of a second.
PL/SQL procedure successfully completed.
Elapsed: 00:00:12.60
但是,如果你立即再次运行相同的代码块,那么你很可能会看到整数版运行速度稍快的反向。
SQL> /
Average elapsed (number) = 1.256 hundredths of a second.
Average elapsed (integer) = 1.22 hundredths of a second.
PL/SQL procedure successfully completed.
Elapsed: 00:00:12.38
实际上,在您尝试测量毫秒或几分之一毫秒的差异时,您就可以进入系统噪声发挥作用的领域。尽管我正在运行的测试之外我的机器处于“空闲”状态,但有数千个原因可能导致系统为处理某些中断或运行某些后台线程而增加额外的毫秒或两秒时间。对于操作系统。
当您认为INTEGER
只是NUMBER(38)
SQL> desc fg_test1;
Name Null? Type
----------------------------------------- -------- ----------------------------
A NUMBER(38)
SQL> desc fg_test;
Name Null? Type
----------------------------------------- -------- ----------------------------
A NUMBER
更新
即使使用NUMBER(6)(请注意,INSERT
必须更改为仅加载999,999行而不是100万行),所以没有变化
创建表格
SQL> create table fg_test2(a number(6));
Table created.
Elapsed: 00:00:00.01
SQL> ed
Wrote file afiedt.buf
1 insert into fg_test2
2* select level from dual connect by level <= 1000000-1
SQL> /
999999 rows created.
Elapsed: 00:00:07.61
SQL> create index fg_ix2 on fg_test2(a);
Index created.
Elapsed: 00:00:00.01
运行脚本。请注意,四次运行中的任何一次都没有显着差异,并且(偶然)四种情况都不是NUMBER(6)
表最有效。
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_start_time number;
3 l_end_time number;
4 l_cnt number;
5 l_iterations number := 500;
6 begin
7 l_start_time := dbms_utility.get_time();
8 for i in 1 .. l_iterations
9 loop
10 select count(*)
11 into l_cnt
12 from fg_test;
13 end loop;
14 l_end_time := dbms_utility.get_time();
15 dbms_output.put_line( 'Average elapsed (number) = ' ||
16 (l_end_time - l_start_time)/l_iterations ||
17 ' hundredths of a second.' );
18 l_start_time := dbms_utility.get_time();
19 for i in 1 .. l_iterations
20 loop
21 select count(*)
22 into l_cnt
23 from fg_test1;
24 end loop;
25 l_end_time := dbms_utility.get_time();
26 dbms_output.put_line( 'Average elapsed (integer) = ' ||
27 (l_end_time - l_start_time)/l_iterations ||
28 ' hundredths of a second.' );
29 l_start_time := dbms_utility.get_time();
30 for i in 1 .. l_iterations
31 loop
32 select count(*)
33 into l_cnt
34 from fg_test2;
35 end loop;
36 l_end_time := dbms_utility.get_time();
37 dbms_output.put_line( 'Average elapsed (number(6)) = ' ||
38 (l_end_time - l_start_time)/l_iterations ||
39 ' hundredths of a second.' );
40* end;
SQL> /
Average elapsed (number) = 1.236 hundredths of a second.
Average elapsed (integer) = 1.234 hundredths of a second.
Average elapsed (number(6)) = 1.306 hundredths of a second.
PL/SQL procedure successfully completed.
Elapsed: 00:00:18.89
SQL> /
Average elapsed (number) = 1.208 hundredths of a second.
Average elapsed (integer) = 1.228 hundredths of a second.
Average elapsed (number(6)) = 1.312 hundredths of a second.
PL/SQL procedure successfully completed.
Elapsed: 00:00:18.74
SQL> /
Average elapsed (number) = 1.208 hundredths of a second.
Average elapsed (integer) = 1.232 hundredths of a second.
Average elapsed (number(6)) = 1.288 hundredths of a second.
PL/SQL procedure successfully completed.
Elapsed: 00:00:18.66
SQL> /
Average elapsed (number) = 1.21 hundredths of a second.
Average elapsed (integer) = 1.22 hundredths of a second.
Average elapsed (number(6)) = 1.292 hundredths of a second.
PL/SQL procedure successfully completed.
Elapsed: 00:00:18.62
答案 1 :(得分:0)
更新:我的测试有一个小问题。 (我尝试第一个表插入10M行,但是连接已经引发了一个不足的内存异常。但是很可能插入了2-3M行然后进行了rolbaked。所以,我的第一个表有相同的行数,但是更多的块。)
因此,下面的断言未经过验证。
<击> 答案是肯定的。
(但是你从中获得了多少,你应该对你的关键操作进行测试。)
INTEGER
是NUMBER
的子类型。但是,令人惊讶的是,NUMBER的子信息总是更快(需要链接在这里)。
我的测试用例:
create table fg_test(a number);
insert into fg_test
select level from dual connect by level <= 1000000;
--1000000 rows inserted
create index fg_ix on fg_test(a);
select count(*) from fg_test;
-- >141 msecs
create table fg_test1(a INTEGER);
insert into fg_test1
select level from dual connect by level <= 1000000;
--1000000 rows inserted
create index fg_ix1 on fg_test1(a);
select count(*) from fg_test1;
-- > 116 msecs
说明:select count(*)
将对索引进行快速全面扫描。我跑了select count(*)
多次,看看最好的速度是多少。通常,INTEGER
为faster
。 INTEGER
的最佳速度更好,而不是NUMBER
的最佳速度;
击>