2012-01-25 6 views
2

現在、NUMBERとして宣言されている整数値のみの列があります。それと同時に、それは私たちの(唯一の)指標です。もしあなたがINTEGERとしてインデックスを宣言すれば、それはパフォーマンスの違いをもたらすだろうか?または、オラクルはそれが整数であることを知るのに十分にスマートですか?どうもありがとうございました。Oracle 10gのNUMBER列の索引

+1

なぜあなたはそれを試してみませんか? – skaffman

+0

Oracleはさらにスマートであり、すべての値が整数であることをチェックしません。たとえそれがあったとしても、あとで非整数値を追加することができるからです。 –

答えて

4

いいえ、そうではありません。

フロリンのテストテーブルを使用して、各クエリを何回実行して、経過時間の平均をとる小さなテストハーネスをセットアップできます。私の場合は、両方のクエリをそれぞれ500回実行しました。

時々、NUMBERのバージョンが少し速くなります(1,232分の1秒対1.284分の1秒)。

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 

は、あなたは、システムノイズが遊びに来ることを行っている領域に入ってもです。私のマシンは、私が走っているテスト以外の「アイドル」であるにもかかわらず、何らかの割り込みを処理したり何かを行うバックグラウンドスレッドを実行するのに、システムが余分なミリ秒または2時間を余分に追加する理由は何千もありますオペレーティングシステム用。

あなたはINTEGERNUMBER(38)

SQL> desc fg_test1; 
Name          Null? Type 
----------------------------------------- -------- ---------------------------- 
A             NUMBER(38) 

SQL> desc fg_test; 
Name          Null? Type 
----------------------------------------- -------- ---------------------------- 
A             NUMBER 

更新のためだけの同義語であることを考えると、この結果は理にかなって:INSERTは負荷に変更されている必要があり

が偶数(6)を使用して、(唯一の999,999行ではなく、100万)、何の変化

テーブルを作成します

はありません

スクリプトを実行します。 4つの実行のいずれにも大きな相違はなく、4つのケースのいずれにおいても(偶然によって)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 
+0

OK。私の理想を証拠にするには、NUMBER(6)でテーブルfg_test1を作成してみてください。あなたのスクリプトでは、数字(6)の時間は常に数字の半分です。 –

+0

@FlorinGhita - 'NUMBER(6)'が 'NUMBER'または' INTEGER'よりも効率的ではないというデモンストレーションを投稿しました。あなたが何か違う何かを見ているなら、あなたのテストを投稿してください。 –

+0

私はテストで私の間違いを見つけたと思う。私は10M行を挿入するために最初のテーブルを試しましたが、接続すると不十分なメモリ例外が発生しました。しかし、確かに2〜3Mの行が挿入されてロールバックされた。だから、私の最初のテーブルは同じ数の行を持っていましたが、より多くのブロックがありました。 :)申し訳ありませんが私の主張。 –

0

更新:私のテストには小さな問題がありました。 (最初のテーブルには10M行を挿入しようとしましたが、接続するとメモリ不足が発生しましたが、確かに2-3M行が挿入されてロールバックされていました。 )

したがって、以下のアサーションは検証されません。

答えははいです。

(しかし、あなたはここから入手どのくらい、あなたは重要な操作でテストする必要があります。)

INTEGERNUMBERのサブタイプです。しかし、驚くべきことに、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(*) muuuult回走って最高のスピードがどのようになっているかを見ました。一般に、 INTEGERfasterです。 INTEGERの最高速度は NUMBERの最高速度よりもが良い です。

+2

'INTEGER'は" *サブタイプ* "ではなく、単にNUMBER(22)の同義語です。あなたのテストは何も表示しません。実行時の(非常に小さな)相違は、他の事柄によっても非常によく起こる可能性があります。 –

+0

@a_horse_with_no_nameもっと関連性の高いテストを行うことができますか?私は正しいと思う。 (私はPL/SQLコースで "サブタイプ"と "スピード"を聞いたことがあります) –

+0

@FlorinGhita - PLS_INTEGERのようなPL/SQLデータ型については、 'NUMBER'データ型よりもPL/SQL数値型操作の方が適していますか? http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5340131040835 –