如果我在Oracle表中使用虚拟列,是否存在任何重大性能问题?
我们有一个场景,其中db将字段存储为字符串。由于其他生产应用程序在这些字段上运行,我们无法轻松转换它们。
我的任务是从同一个数据库生成报告。由于我需要能够按日期过滤(存储为字符串),因此我注意到我们可以创建一个虚拟日期字段,以便我可以查询它。
有没有人用这种方法遇到任何障碍?
答案 0 :(得分: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