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

时间:2016-08-15 11:11:46

标签: oracle

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

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

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

有没有人用这种方法遇到任何障碍?

1 个答案:

答案 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