热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

【OracleDatabase12cNewFeature】ILM–TemporalVa

ILM全称是InformationLifecycleManagement,意思是信息生命周期管理,听上去很高端洋气的一个词,但是实际上几乎每个稍微大些的系统都已经在做ILM了,比如说将生产表中的数据定期插入到历史表中,并把生产表中的这些数据删除,这就是数据生命周期管理;又

ILM全称是Information Lifecycle Management,意思是信息生命周期管理,听上去很高端洋气的一个词,但是实际上几乎每个稍微大些的系统都已经在做ILM了,比如说将生产表中的数据定期插入到历史表中,并把生产表中的这些数据删除,这就是数据生命周期管理;又

ILM全称是Information Lifecycle Management,意思是信息生命周期管理,听上去很高端洋气的一个词,但是实际上几乎每个稍微大些的系统都已经在做ILM了,比如说将生产表中的数据定期插入到历史表中,并把生产表中的这些数据删除,这就是数据生命周期管理;又比如使用了分区,定期将过期的数据分区删除掉,或者置为READONLY,让RMAN不再备份,这也是数据生命周期管理。

因此ILM由来已久,只要数据存在活跃-不活跃-静止这样的周期变化,那么ILM就必不可少,Oracle Database 12c中提供了很多新功能用来方便地进行数据生命周期管理,有些功能甚至是我们期盼已久的。

本文先介绍时间有效期管理(Temporal Validity),下两篇文章会介绍数据库内归档(In-Database Archiving)以及数据热度图(Heat Map)。注意:Temporal Validity和Heat Map目前还不支持多租户架构的数据库,因此想要使用,必须是一个NON-CDB,In-Database Archiving则支持多租户架构,可以在PDB中使用。

一. 时间有效期管理(Temporal Validity)
以下简称TV,TV的功能大致上可以这样描述:在表中手动或者自动建两个时间类型的字段,一个表示有效期的开始时间,一个表示有效期的结束时间,就可以通过设置让只有在有效期内的记录才会被选择出来。

以下这个场景是我构想出来的,一张表里不断地INSERT数据,但是每条数据有效期只有1分钟,过了1分钟再查就看不见了,如果加以仔细策划,应该会是很有趣的功能。直接进入测试。

设置TV,需要使用dbms_flashback_archive包,需要该包的执行权限。

SQL> GRANT EXECUTE ON dbms_flashback_archive TO kamus;

创建测试表,period for关键字是TV新功能的关键字,valid_time是TV策略的名字,可以随便写。valid_time_start和valid_time_end字段可以不手工定义,只要指定了period for关键字,Oracle会自动创建两个不可见字段。我这里之所以手工定义开始和结束时间字段,是为了能够指定DEFAULT值。有效期开始时间valid_time_start是记录插入的当前时间,有效期结束时间valid_time_end是当前时间的后一分钟。由此定义出了一个跨度1分钟的有效期。

SQL> conn kamus/oracle
SQL> CREATE TABLE TV (insert_time DATE, 
valid_time_start DATE invisible DEFAULT sysdate, 
valid_time_end DATE invisible DEFAULT sysdate+1/1440, 
period FOR valid_time(valid_time_start,valid_time_end)
);

可以看到明确定义的INSERT_TIME字段用于演示,VALID_TIME_START和VALID_TIME_END是明确定义的不可见字段。之外,Oracle还自动创建了VALID_TIME字段,也是隐藏字段。

SQL> SELECT COLUMN_NAME,DATA_TYPE,HIDDEN_COLUMN FROM USER_TAB_COLS WHERE TABLE_NAME='TV';
?
COLUMN_NAME          DATA_TYPE            HID
-------------------- -------------------- ---
VALID_TIME_END       DATE                 YES
VALID_TIME_START     DATE                 YES
INSERT_TIME          DATE                 NO
VALID_TIME           NUMBER               YES

插入一行当前时间

SQL> INSERT INTO TV VALUES (sysdate);
?
1 ROW created.

正常情况选择,这行记录总是存在的

SQL> SELECT * FROM TV;
?
INSERT_TIME
-----------------
20130811 09:04:30

为了应对这个新功能,在Flashback Query中新增了as of period for关键字。as of period for valid_time sysdate+1表示我们想查询在明天都还有效的数据,因为根据我们的设定,所有数据都只在插入以后1分钟内有效,因此自然无法找到在明天还有效的数据,返回零条记录。

SQL> SELECT * FROM TV AS OF period FOR valid_time sysdate+1;
?
no ROWS selected

再插入一条测试数据。

SQL> INSERT INTO TV VALUES (sysdate);
?
1 ROW created.
?
SQL> SELECT * FROM TV;
?
INSERT_TIME
-----------------
20130811 09:04:30
20130811 09:08:27

我们想查询昨天就有效的数据,但是所有的数据有效期开始都是插入数据的那个时间点,自然无法找到昨天就有效的数据,返回零条记录。

SQL> SELECT * FROM TV AS OF period FOR valid_time sysdate-1;
?
no ROWS selected

除了使用as of这种闪回查询的语法,还可以直接在会话级别设置有效时间点。CURRENT表示设置为当前时间点。

SQL> EXEC dbms_flashback_archive.enable_at_valid_time('CURRENT');
?
PL/SQL PROCEDURE successfully completed.
?
SQL> SELECT * FROM TV;
?
no ROWS selected

在我的测试过程中,TV并不稳定,有时候即使设置了as of,也仍然会返回所有记录,但是过一会儿再次执行完全相同的语句,又能够返回符合条件的记录。没有详细跟踪不稳定的原因,但是猜测与cursor执行计划重用有关,毕竟Oracle的实现只是增加了一个filter条件,如果由于某种原因,之前cursor的执行计划被重用,那么很可能这个filter条件就没有加上,随之而来的也就会返回所有记录。

接下来,我们通过显示执行计划,看看Oracle是如何增加这个filter条件的。
首先禁用TV。执行计划是很正常的全表扫描。

SQL> EXEC dbms_flashback_archive.DISABLE_ASOF_VALID_TIME;
?
PL/SQL PROCEDURE successfully completed.
?
SQL> SELECT COUNT(*) FROM tv;
?
  COUNT(*)
----------
     77477
?
?
Execution Plan
----------------------------------------------------------
Plan hash VALUE: 4129329588
?
-------------------------------------------------------------------
| Id  | Operation          | Name | ROWS  | Cost (%CPU)| TIME     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   102   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TV   | 76349 |   102   (0)| 00:00:01 |
-------------------------------------------------------------------
?
Note
-----
   - dynamic statistics used: dynamic sampling (level=2)
?
?
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        333  consistent gets
          0  physical reads
          0  redo SIZE
        544  bytes sent via SQL*Net TO client
        543  bytes received via SQL*Net FROM client
          2  SQL*Net roundtrips TO/FROM client
          0  sorts (memory)
          0  sorts (disk)
          1  ROWS processed

重新在会话级别启用TV,可以看到在第二步,也就是全表扫描之后增加了一个filter,由于指定的有效期是CURRENT,因此filter条件是VALID_TIME_START 小于等于 当前时间 小于 VALID_TIME_END,也就是只要指定的有效期落在VALID_TIME_START和VALID_TIME_END之间,这条记录就可以被显示出来。同时也可以看到如果这两个限制条件为空,也都作为开放区间,也就是为空就表示不做限制。
由于测试的记录都只有1分钟有效期,因此此时已经没有一条记录可以显示了。

SQL> EXEC dbms_flashback_archive.enable_at_valid_time('CURRENT');
?
PL/SQL PROCEDURE successfully completed.
?
SQL> SELECT COUNT(*) FROM tv;
?
  COUNT(*)
----------
         0
?
?
Execution Plan
----------------------------------------------------------
Plan hash VALUE: 4129329588
?
---------------------------------------------------------------------------
| Id  | Operation          | Name | ROWS  | Bytes | Cost (%CPU)| TIME     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |    18 |   103   (1)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |    18 |            |          |
|*  2 |   TABLE ACCESS FULL| TV   |   287 |  5166 |   103   (1)| 00:00:01 |
---------------------------------------------------------------------------
?
Predicate Information (IDENTIFIED BY operation id):
---------------------------------------------------
?
   2 - FILTER(("T"."VALID_TIME_START" IS NULL OR
              SYS_EXTRACT_UTC(INTERNAL_FUNCTION("T"."VALID_TIME_START"))<=SYS_EXTRACT_
              UTC(SYSTIMESTAMP(6))) AND ("T"."VALID_TIME_END" IS NULL OR
              SYS_EXTRACT_UTC(INTERNAL_FUNCTION("T"."VALID_TIME_END"))>SYS_EXTRACT_UTC
              (SYSTIMESTAMP(6))))
?
?
Statistics
----------------------------------------------------------
         33  recursive calls
          4  db block gets
        354  consistent gets
          0  physical reads
          0  redo SIZE
        541  bytes sent via SQL*Net TO client
        543  bytes received via SQL*Net FROM client
          2  SQL*Net roundtrips TO/FROM client
          0  sorts (memory)
          0  sorts (disk)
          1  ROWS processed

通过执行计划显示后台机制是一方面,另一方面我们也可以看到实际上TV是会有性能问题的,如果WHERE条件中无法使用到索引而执行了全表扫描(我这里因为没有WHERE条件所以只能是全表扫描),那么无论最终符合有效期的记录是多少,总要先进行所有记录的扫描,我们可以通过前后两次的consistent gets基本相同来获得这个结论。

更直白的说,如果作为系统设计人员不去考虑索引的构建,而仅仅是启用了TV,那么哪怕根据有效期限制,有10万记录的表只有1条会被显示出来,也仍然需要先扫描10万记录,然后再filter掉99999条,这对于程序员来说,如果不仔细阅读执行计划,就可能会造成很大的困扰,程序员会很奇怪,为什么这张表里面看上去只有1条记录,但是却要扫描那么长时间呢?

结论:数据有效期是Oracle利用隐藏字段和Flashback Query技术作的一个有趣的功能,但是数据架构人员在规划的时候一定要考虑性能因素。

Share/Save

Related posts:

  1. Oracle 11g new feature &#8211; Virtual Column
  2. SPM default feature in Oracle 11g
  3. How to Use DBMS_ADVANCED_REWRITE in Oracle 10g
YARPP
推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 35岁程序员连续被2家公司裁掉,网友酸了,成功入职成事业编晒出福利
    这篇文章讲述了一个35岁程序员连续被两家公司裁掉的故事,他在遭遇中年危机后成功入职事业单位,并分享了入职后的福利。文章探讨了程序员在互联网行业中的竞争力下降的原因。 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Python版Protobuf的安装和使用方法,包括版本选择、编译配置、示例代码等内容。通过学习本教程,您将了解如何在Python中使用Protobuf进行数据序列化和反序列化操作,以及相关的注意事项和技巧。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了2019年上半年内蒙古计算机软考考试的报名通知和考试时间。考试报名时间为3月1日至3月23日,考试时间为2019年5月25日。考试分为高级、中级和初级三个级别,涵盖了多个专业资格。报名采取网上报名和网上缴费的方式进行,报考人员可登录内蒙古人事考试信息网进行报名。详细内容请点击查看。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Oracle10g备份导入的方法及注意事项
    本文介绍了使用Oracle10g进行备份导入的方法及相关注意事项,同时还介绍了2019年独角兽企业重金招聘Python工程师的标准。内容包括导出exp命令、删用户、创建数据库、授权等操作,以及导入imp命令的使用。详细介绍了导入时的参数设置,如full、ignore、buffer、commit、feedback等。转载来源于https://my.oschina.net/u/1767754/blog/377593。 ... [详细]
author-avatar
敏捷的敏2502921017
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有