2
如果我在Oracle表中使用虛擬列,是否有任何主要的性能問題?如果我在Oracle中使用虛擬列,是否有任何主要的性能問題?
我們有一個場景,其中數據庫的字段存儲爲字符串。由於其他生產應用程序跑出這些領域,我們不能輕易轉換它們。
我的任務是從同一個數據庫生成報告。由於我需要能夠按日期過濾(存儲爲字符串),因此我注意到我們可以創建一個虛擬日期字段,以便我可以對此進行查詢。
有沒有人遇到過這種方法的任何障礙?
如果我在Oracle表中使用虛擬列,是否有任何主要的性能問題?如果我在Oracle中使用虛擬列,是否有任何主要的性能問題?
我們有一個場景,其中數據庫的字段存儲爲字符串。由於其他生產應用程序跑出這些領域,我們不能輕易轉換它們。
我的任務是從同一個數據庫生成報告。由於我需要能夠按日期過濾(存儲爲字符串),因此我注意到我們可以創建一個虛擬日期字段,以便我可以對此進行查詢。
有沒有人遇到過這種方法的任何障礙?
虛擬列是使用從表中選擇時評估的表達式定義的。在表上插入/更新沒有性能影響。
例如:
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
擴大Tony的回答是:在試圖插入「XX」的錯誤信息可能是在大多數情況下是一件好事(間接數據驗證)。此外,大概在所有使用該字段的查詢中計算'to_date(....)' - 所以與THOSE查詢相比,不應該有性能損失(計算無論如何),並且不能使用索引對於有或沒有虛擬列的datestr也是一樣的。 – mathguy
您可以閱讀更多[這裏](https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:676611400346196844) – michaos