2013-01-17 33 views
7

列長度的乘法因素是否會影響數據庫性能?Oracle首選列長度

換句話說,就是下面兩個表的性能之間的差異:

TBL1: 
    - CLMN1 VARCHAR2(63) 
    - CLMN2 VARCHAR2(129) 
    - CLMN3 VARCHAR2(250) 

TBL2: 
    - CLMN1 VARCHAR2(64) 
    - CLMN2 VARCHAR2(128) 
    - CLMN3 VARCHAR2(256) 

如果我們總是試圖使列的長度與2一些力量還是隻做最大尺寸?

一些開發人員聲稱數據庫中列的長度乘法因子之間存在某種聯繫,因爲它影響Oracle如何在磁盤上分發和保存數據並在內存中共享其緩存。有人可以證明或反駁這個嗎?

+0

您是否嘗試過性能測試? – beny23

+0

不可以,不可以。如果存在差異,理論上的解釋是什麼?由於很多時候開發人員喜歡分配二進制列長度的列(64,128 ...)。我想知道爲什麼?它真的有影響嗎? – Andremoniy

+2

您可能知道開發人員正在考慮散列分區,建議分區數量是2的冪數(http://asktom.oracle.com/pls/asktom/f?p=100:11: 0 :::: P11_QUESTION_ID:1001181800346992268) – Ben

回答

9

性能沒有差異。並且由於2的冪次而沒有進行隱藏優化。

唯一能夠改變事物存儲方式的是實際的數據。存儲在VARCHAR2(2000)列中的100個字符的存儲方式與存儲在VARCHAR2(500)列中的100個字符的存儲方式完全相同。

認爲長度爲業務約束的,而不是數據類型的一部分。唯一能促使你決定長度的決定是關於數據的業務限制。

編輯:唯一的情況,其中長度確實有所作爲,是當你需要了解它的列的索引。較早的Oracle版本(< 10)確實在密鑰長度上有限制,並在創建索引時檢查過。

儘管在Oracle 11中可能,但對於具有4000個字符的值的索引,可能並不是最明智的選擇。

編輯2

所以我很好奇,並設置一個簡單的測試:

create table narrow (id varchar(40)); 
create table wide (id varchar(4000)); 

然後塞滿的40 'X' 組成的字符串兩個表。如果存儲器之間確實存在(實質性)差異,則在檢索數據時應該以某種方式顯示,對嗎?

這兩個表都恰好有1048576行。

 
Connected to: 
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production 
With the Partitioning, OLAP, Data Mining and Real Application Testing options 

SQL> set autotrace traceonly statistics 
SQL> select count(*) from wide; 


Statistics 
---------------------------------------------------------- 
      0 recursive calls 
      1 db block gets 
     6833 consistent gets 
      0 physical reads 
      0 redo size 
     349 bytes sent via SQL*Net to client 
     472 bytes received via SQL*Net from client 
      2 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
      1 rows processed 

SQL> select count(*) from narrow; 


Statistics 
---------------------------------------------------------- 
      0 recursive calls 
      1 db block gets 
     6833 consistent gets 
      0 physical reads 
      0 redo size 
     349 bytes sent via SQL*Net to client 
     472 bytes received via SQL*Net from client 
      2 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
      1 rows processed 

SQL> 

因此,兩個表的全表掃描完全一樣。那麼當我們真正選擇數據時會發生什麼?

 
SQL> select * from wide; 

1048576 rows selected. 


Statistics 
---------------------------------------------------------- 
      4 recursive calls 
      2 db block gets 
     76497 consistent gets 
      0 physical reads 
      0 redo size 
    54386472 bytes sent via SQL*Net to client 
    769427 bytes received via SQL*Net from client 
     69907 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
    1048576 rows processed 

SQL> select * from narrow; 

1048576 rows selected. 


Statistics 
---------------------------------------------------------- 
      4 recursive calls 
      2 db block gets 
     76485 consistent gets 
      0 physical reads 
      0 redo size 
    54386472 bytes sent via SQL*Net to client 
    769427 bytes received via SQL*Net from client 
     69907 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
    1048576 rows processed 

SQL> 

一致性獲取有一個細微的差異,但這可能是由於緩存。

+0

好的。所以,你聲稱,列的長度對Oracle如何在內存中分配磁盤和數據庫緩存上的數據庫文件沒有任何影響,所以乘法因子沒有任何意義? – Andremoniy

+2

只有數據的* actual *長度影響這個,而不是聲明的最大長度。 (當然還有其他配置屬性,如PCTFREE) –

+0

這與我一直對我感興趣的事情有關(儘管看起來不足以真正查看它)。那麼你是說真的在varchar(2000)和varchar(500)之間的性能沒有什麼區別嗎?它會解決我與運行Oracle數據庫的女性在我工作的那個女性之間經常發生的(良性)分歧...... –