2016-08-15 15 views
2

如果我在Oracle表中使用虛擬列,是否有任何主要的性能問題?如果我在Oracle中使用虛擬列,是否有任何主要的性能問題?

我們有一個場景,其中數據庫的字段存儲爲字符串。由於其他生產應用程序跑出這些領域,我們不能輕易轉換它們。

我的任務是從同一個數據庫生成報告。由於我需要能夠按日期過濾(存儲爲字符串),因此我注意到我們可以創建一個虛擬日期字段,以便我可以對此進行查詢。

有沒有人遇到過這種方法的任何障礙?

回答

3

虛擬列是使用從表中選擇時評估的表達式定義的。在表上插入/更新沒有性能影響。

例如:

create table t1 (
    datestr varchar2(100), 
    datedt date generated always as (to_date(datestr,'YYYYMMDD')) 
    ); 

Table created. 
SQL> insert into t1 (datestr) values ('20160815'); 

1 row created. 

SQL> insert into t1 (datestr) values ('xxx'); 

1 row created. 

SQL> commit; 

Commit complete. 

請注意,我是能夠插入一個無效的日期值到datestr。現在,我們可以嘗試選擇數據:

SQL> select * from t1 where datedt = date '2016-08-15'; 
ERROR: 
ORA-01841: (full) year must be between -4713 and +9999, and not be 0 

這可能是你的問題,如果你不能保證所有的字符串持有有效日期。

至於性能,當你運行上面的查詢你真正運行是:

select * from t1 where to_date(datestr,'YYYYMMDD') = date '2016-08-15'; 

所以查詢將無法對datestr列(可能)使用一個索引,你可能想要在虛擬列上添加索引。同樣,如果任何字符串不包含有效日期,這將不起作用。

另一個考慮是對現有代碼的潛在影響。希望你不會有像insert into t1 values (...);這樣的代碼,即不指定列列表。如果你這樣做,你會得到錯誤:

ORA-54013: INSERT operation disallowed on virtual columns 
+0

擴大Tony的回答是:在試圖插入「XX」的錯誤信息可能是在大多數情況下是一件好事(間接數據驗證)。此外,大概在所有使用該字段的查詢中計算'to_date(....)' - 所以與THOSE查詢相比,不應該有性能損失(計算無論如何),並且不能使用索引對於有或沒有虛擬列的datestr也是一樣的。 – mathguy

+0

您可以閱讀更多[這裏](https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:676611400346196844) – michaos

相關問題