如果我在Oracle中使用虚拟列,是否存在重大性能问题?

如果我在Oracle中使用虚拟列,是否存在重大性能问题?,oracle,Oracle,如果在Oracle表中使用虚拟列,是否存在任何主要性能问题 我们有一个场景,其中db将字段存储为字符串。由于其他生产应用程序运行这些字段,我们无法轻松转换它们 我的任务是从同一数据库生成报告。由于我需要能够按日期(存储为字符串)进行过滤,因此我注意到我们可以创建一个虚拟日期字段,以便我可以查询该字段 有人使用这种方法遇到过任何障碍吗?使用从表中选择时计算的表达式定义虚拟列。表上的插入/更新没有性能影响 例如: create table t1 ( datestr varchar2(100)

如果在Oracle表中使用虚拟列,是否存在任何主要性能问题

我们有一个场景,其中db将字段存储为字符串。由于其他生产应用程序运行这些字段,我们无法轻松转换它们

我的任务是从同一数据库生成报告。由于我需要能够按日期(存储为字符串)进行过滤,因此我注意到我们可以创建一个虚拟日期字段,以便我可以查询该字段


有人使用这种方法遇到过任何障碍吗?

使用从表中选择时计算的表达式定义虚拟列。表上的插入/更新没有性能影响

例如:

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
列上使用索引(可能),您可能需要在虚拟列上添加索引。同样,如果任何字符串不包含有效日期,这将不起作用

另一个考虑因素是对现有代码的潜在影响。希望您不会有任何类似于插入t1值(…)的代码即不指定列列表。如果您这样做,您将得到错误:

ORA-54013: INSERT operation disallowed on virtual columns

扩展Tony的回答:在大多数情况下,尝试插入“xx”时的错误消息可能是一件好事(间接数据验证)。此外,人们可能会在所有使用该字段的查询中计算
to_date(..)
,因此与这些查询相比,不会有性能损失(不管计算是如何完成的),并且无法在datestr上使用索引也会与使用或不使用虚拟列相同。您可以阅读更多内容