飞道的博客

《收获,不止Oracle》表的设计之五朵金花

293人阅读  评论(0)

 表设计主要强调什么场合该选择什么技术,没有最高级的技术,只有最适合的技术。

1.表的特性

普通堆表的不足之处

 1.查看产生多少日志


  
  1. [oracle @oracle -db -19c ~]$ sqlplus / as sysdba
  2. SQL *Plus: Release 19.0 .0 .0 .0 - Production on Wed Jan 4 14: 27: 13 2023
  3. Version 19.3 .0 .0 .0
  4. Copyright (c) 1982, 2019, Oracle. All rights reserved.
  5. Connected to:
  6. Oracle Database 19c Enterprise Edition Release 19.0 .0 .0 .0 - Production
  7. Version 19.3 .0 .0 .0
  8. SQL > alter session set container =PDB1;
  9. Session altered.
  10. SQL > select a.name,b.value
  11. 2 from v$statname a,v$mystat b
  12. 3 where a.statistic# =b.statistic#
  13. 4 and a.name = 'redo size';
  14. NAME
  15. --------------------------------------------------------------------------------
  16. VALUE
  17. ----------
  18. redo size
  19. 0
  20. SQL >

  
  1. [oracle @MaxwellDBA ~]$ sqlplus / as sysdba
  2. SQL *Plus: Release 19.0 .0 .0 .0 - Production on Wed Jan 4 15: 25: 31 2023
  3. Version 19.3 .0 .0 .0
  4. Copyright (c) 1982, 2019, Oracle. All rights reserved.
  5. Connected to:
  6. Oracle Database 19c Enterprise Edition Release 19.0 .0 .0 .0 - Production
  7. Version 19.3 .0 .0 .0
  8. sys @cdb$root:orclcdb > alter session set container =ORCLPDB1;
  9. Session altered.
  10. sys @cdb$root:orclcdb > select a.name,b.value
  11. 2 from v$statname a,v$mystat b
  12. 3 where a.statistic# =b.statistic#
  13. 4 and a.name = 'redo size';
  14. NAME VALUE
  15. ---------------------------------------------------------------- ----------
  16. redo size 0
  17. 1 row selected.
  18. sys @cdb$root:orclcdb >

实验准备工作,创建观察redo的视图


  
  1. [oracle @MaxwellDBA ~]$ sqlplus / as sysdba
  2. SQL *Plus: Release 19.0 .0 .0 .0 - Production on Wed Jan 4 15: 25: 31 2023
  3. Version 19.3 .0 .0 .0
  4. Copyright (c) 1982, 2019, Oracle. All rights reserved.
  5. Connected to:
  6. Oracle Database 19c Enterprise Edition Release 19.0 .0 .0 .0 - Production
  7. Version 19.3 .0 .0 .0
  8. sys @cdb$root:orclcdb > alter session set container =ORCLPDB1;
  9. Session altered.
  10. sys @cdb$root:orclcdb > select a.name,b.value
  11. 2 from v$statname a,v$mystat b
  12. 3 where a.statistic# =b.statistic#
  13. 4 and a.name = 'redo size';
  14. NAME VALUE
  15. ---------------------------------------------------------------- ----------
  16. redo size 0
  17. 1 row selected.
  18. sys @cdb$root:orclcdb >

观察删除记录产生了多少redo


  
  1. SQL > select * from v_redo_size;
  2. NAME
  3. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  4. VALUE
  5. ----------
  6. redo size
  7. 11871068
  8. SQL > delete from t;
  9. 73262 rows deleted.
  10. SQL > select * from v_redo_size;
  11. NAME
  12. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  13. VALUE
  14. ----------
  15. redo size
  16. 22920220
  17. SQL > select 22920220 - 11871068 from dual;
  18. 22920220 -11871068
  19. -----------------
  20. 11049152
  21. SQL >

删除语句产生了差不多11M的日志量

观察插入记录产生了多少redo


  
  1. SQL >
  2. SQL > insert into t select * from dba_objects;
  3. 73264 rows created.
  4. SQL > select * from v_redo_size;
  5. NAME
  6. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  7. VALUE
  8. ----------
  9. redo size
  10. 34265784
  11. SQL > select 34265784 - 22920220 from dual;
  12. 34265784 -22920220
  13. -----------------
  14. 11345564
  15. SQL >

观察更新记录产生了多少redo


  
  1. SQL >
  2. SQL > update t set object_id =rownum;
  3. 73264 rows updated.
  4. SQL > select * from v_redo_size;
  5. NAME
  6. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  7. VALUE
  8. ----------
  9. redo size
  10. 47178732
  11. SQL > select 47178732 - 34265784 from dual;
  12. 47178732 -34265784
  13. -----------------
  14. 12912948
  15. SQL >

更新语句产生了差不多12M的redo

三个试验说明了对表的更新操作,无论是删除、插入还是修改,都会产生日志.

虽说安全第一,不过在某些特定的场合,某些表的记录只是作为中间结果临时运算而根本无须永久保留,这些表无须写日志,那就既高效又安全了!

delete无法释放空间

实际上工作中不少性能问题都和delete操作有关。

原因是:delete是最耗性能的操作,产生的undo最多,而且因为undo需要redo来保护的缘故,delete产生的redo量也最大。所以不少性能问题都和delete操作有关。

观察未删除表时产生的逻辑读


  
  1. SQL > show user;
  2. USER is "MAXWELLPAN"
  3. SQL > drop table t purge;
  4. Table dropped.
  5. SQL >
  6. SQL > create table t as select * from dba_objects;
  7. Table created.
  8. SQL > set autotrace on
  9. SQL > select count( *) from t;
  10. COUNT( *)
  11. ----------
  12. 73263
  13. Execution Plan
  14. ----------------------------------------------------------
  15. Plan hash value: 2966233522
  16. -------------------------------------------------------------------
  17. | Id | Operation | Name | Rows | Cost ( %CPU) | Time |
  18. -------------------------------------------------------------------
  19. | 0 | SELECT STATEMENT | | 1 | 397 ( 1) | 00: 00: 01 |
  20. | 1 | SORT AGGREGATE | | 1 | | |
  21. | 2 | TABLE ACCESS FULL | T | 73263 | 397 ( 1) | 00: 00: 01 |
  22. -------------------------------------------------------------------
  23. Statistics
  24. ----------------------------------------------------------
  25. 75 recursive calls
  26. 0 db block gets
  27. 1546 consistent gets
  28. 1422 physical reads
  29. 0 redo size
  30. 552 bytes sent via SQL *Net to client
  31. 384 bytes received via SQL *Net from client
  32. 2 SQL *Net roundtrips to / from client
  33. 20 sorts (memory)
  34. 0 sorts (disk)
  35. 1 rows processed
  36. SQL >

用delete命令删除t所有记录后,逻辑读发生了微小的变化


  
  1. SQL >
  2. SQL > set autotrace off
  3. SQL > delete from t;
  4. 73263 rows deleted.
  5. SQL > commit;
  6. Commit complete.
  7. SQL > set autotrace on
  8. SQL > select count( *) from t;
  9. COUNT( *)
  10. ----------
  11. 0
  12. Execution Plan
  13. ----------------------------------------------------------
  14. Plan hash value: 2966233522
  15. -------------------------------------------------------------------
  16. | Id | Operation | Name | Rows | Cost ( %CPU) | Time |
  17. -------------------------------------------------------------------
  18. | 0 | SELECT STATEMENT | | 1 | 397 ( 1) | 00: 00: 01 |
  19. | 1 | SORT AGGREGATE | | 1 | | |
  20. | 2 | TABLE ACCESS FULL | T | 73263 | 397 ( 1) | 00: 00: 01 |
  21. -------------------------------------------------------------------
  22. Statistics
  23. ----------------------------------------------------------
  24. 0 recursive calls
  25. 0 db block gets
  26. 1426 consistent gets
  27. 0 physical reads
  28. 0 redo size
  29. 549 bytes sent via SQL *Net to client
  30. 384 bytes received via SQL *Net from client
  31. 2 SQL *Net roundtrips to / from client
  32. 0 sorts (memory)
  33. 0 sorts (disk)
  34. 1 rows processed
  35. SQL >

使用truncate命令清空表后,逻辑读终于大幅度下降了。


  
  1. SQL >
  2. SQL > set autotrace off
  3. SQL > truncate table t;
  4. Table truncated.
  5. SQL > set autotrace on
  6. SQL > select count( *) from t;
  7. COUNT( *)
  8. ----------
  9. 0
  10. Execution Plan
  11. ----------------------------------------------------------
  12. Plan hash value: 2966233522
  13. -------------------------------------------------------------------
  14. | Id | Operation | Name | Rows | Cost ( %CPU) | Time |
  15. -------------------------------------------------------------------
  16. | 0 | SELECT STATEMENT | | 1 | 397 ( 1) | 00: 00: 01 |
  17. | 1 | SORT AGGREGATE | | 1 | | |
  18. | 2 | TABLE ACCESS FULL | T | 73263 | 397 ( 1) | 00: 00: 01 |
  19. -------------------------------------------------------------------
  20. Statistics
  21. ----------------------------------------------------------
  22. 1 recursive calls
  23. 1 db block gets
  24. 3 consistent gets
  25. 0 physical reads
  26. 104 redo size
  27. 549 bytes sent via SQL *Net to client
  28. 384 bytes received via SQL *Net from client
  29. 2 SQL *Net roundtrips to / from client
  30. 0 sorts (memory)
  31. 0 sorts (disk)
  32. 1 rows processed
  33. SQL >

delete 删除并不能释放空间,虽然delete将很多块的记录删除了,但是空块依然保留,Oracle在查询时依然会去查询这些空块。而truncate是一种释放高水平位的动作,这些空块被回收,空间也被释放了。

不过truncate显然不能替代delete,因为truncate是一种DDL操作而非DML操作,truncate后面是不能带条件的,即truncate table t where…是不允许的。但是如果表中这些where条件能形成有效的分区,Oracle是支持在分区表中做truncate分区的,命令大致为 alter table t truncate partition '分区名',如果where 条件就是分区条件,那等同于换个角度实现了 truncate table t where…的功能。

这就是分区表最实用的功能之一了,高效地清理数据,释放空间,老师将在后续章节中详细描述分区表的特性。

表记录太多检索较慢

有没有什么好方法能提升检索的速度呢?主要思路就是缩短访问路径来完成同样的更新查询操作。简单地说,完成同样的需求,访问块的个数越少越好。Oracle 为了尽可能减少访问路径提供了两种主要技术,一种是索引技术,另一种则是分区技术。

索引本身也是一把双刃剑,既能给数据库开发应用带来极大的帮助,也会给数据库带来不小的灾难。

分区表,除了之前描述的具有高效清理数据的功能外,还有减少访问路径的神奇本领。

索引回表读开销很大

观察TABLE ACCESS BY INDEX ROWID 产生的开销


  
  1. SQL >
  2. SQL > show user;
  3. USER is "MAXWELLPAN"
  4. SQL > drop table t purge;
  5. Table dropped.
  6. SQL > create table t as select * from dba_objects where rownum <= 200;
  7. Table created.
  8. SQL > create index idx_obj_id on t(object_id);
  9. Index created.
  10. SQL > set linesize 1000
  11. SQL > set autotrace traceonly
  12. SQL > select * from t where object_id <= 10;
  13. 9 rows selected.
  14. Execution Plan
  15. ----------------------------------------------------------
  16. Plan hash value: 3784017797
  17. --------------------------------------------------------------------------------------------------
  18. | Id | Operation | Name | Rows | Bytes | Cost ( %CPU) | Time |
  19. --------------------------------------------------------------------------------------------------
  20. | 0 | SELECT STATEMENT | | 9 | 927 | 2 ( 0) | 00: 00: 01 |
  21. | 1 | TABLE ACCESS BY INDEX ROWID BATCHED | T | 9 | 927 | 2 ( 0) | 00: 00: 01 |
  22. | * 2 | INDEX RANGE SCAN | IDX_OBJ_ID | 9 | | 1 ( 0) | 00: 00: 01 |
  23. --------------------------------------------------------------------------------------------------
  24. Predicate Information (identified by operation id):
  25. ---------------------------------------------------
  26. 2 - access("OBJECT_ID" <= 10)
  27. Statistics
  28. ----------------------------------------------------------
  29. 51 recursive calls
  30. 126 db block gets
  31. 54 consistent gets
  32. 3 physical reads
  33. 25504 redo size
  34. 3584 bytes sent via SQL *Net to client
  35. 397 bytes received via SQL *Net from client
  36. 2 SQL *Net roundtrips to / from client
  37. 0 sorts (memory)
  38. 0 sorts (disk)
  39. 9 rows processed
  40. SQL >

有序插入却难有序读出

测试表记录顺序插入却难保证顺序读出


  
  1. [oracle @oracle -db -19c ~]$ sqlplus / as sysdba
  2. SQL *Plus: Release 19.0 .0 .0 .0 - Production on Thu Jan 5 10: 11: 06 2023
  3. Version 19.3 .0 .0 .0
  4. Copyright (c) 1982, 2019, Oracle. All rights reserved.
  5. Connected to:
  6. Oracle Database 19c Enterprise Edition Release 19.0 .0 .0 .0 - Production
  7. Version 19.3 .0 .0 .0
  8. SQL > connect maxwellpan /maxwellpan @PDB1;
  9. Connected.
  10. SQL >
  11. SQL > show user
  12. USER is "MAXWELLPAN"
  13. SQL >
  14. SQL > drop table t purge;
  15. Table dropped.
  16. SQL > create table t
  17. 2 (a int,
  18. 3 b varchar2( 4000) default rpad( '*', 4000, '*'),
  19. 4 c varchar2( 4000) default rpad( '*', 3000, '*'));
  20. Table created.
  21. SQL > insert into t(a) values( 1);
  22. insert into t(a) values( 2);
  23. 1 row created.
  24. SQL > SQL >
  25. 1 row created.
  26. SQL > SQL > SQL > insert into t(a) values( 3);
  27. 1 row created.
  28. SQL > select A from t;
  29. A
  30. ----------
  31. 1
  32. 2
  33. 3
  34. SQL > delete from t where a = 2;
  35. 1 row deleted.
  36. SQL > insert into t(a) values( 4);
  37. 1 row created.
  38. SQL > commit;
  39. Commit complete.
  40. SQL > select A from t;
  41. A
  42. ----------
  43. 1
  44. 4
  45. 3
  46. SQL >

比较有无order by 语句在执行计划、开销上的差异

可以观察到,有排序的操作的统计信息模块有一个1 sorts(memory),表示发生了排序,执行计划中也有SORT ORDER BY关键字,不过最重要的是,没排序的操作代价为3,有排序的操作代价为4,性能上是有差异的,这在数量大的时候将会非常明显。

关于order by 避免排序的方法有两种思路。第一种思路是在order by 的排序列建索引,为什么可以消除排序呢?这就当成一个悬念,在后续介绍索引的章节中给大家揭秘。第二种方法就是,将普通表改造为有序散列聚簇表,这样可以保证顺序插入,order by 展现时无须再有排序动作


  
  1. SQL >
  2. SQL > show user;
  3. USER is "MAXWELLPAN"
  4. SQL > set linesize 1000
  5. SQL > set autotrace traceonly
  6. SQL > select A from t;
  7. Execution Plan
  8. ----------------------------------------------------------
  9. Plan hash value: 1601196873
  10. --------------------------------------------------------------------------
  11. | Id | Operation | Name | Rows | Bytes | Cost ( %CPU) | Time |
  12. --------------------------------------------------------------------------
  13. | 0 | SELECT STATEMENT | | 3 | 39 | 3 ( 0) | 00: 00: 01 |
  14. | 1 | TABLE ACCESS FULL | T | 3 | 39 | 3 ( 0) | 00: 00: 01 |
  15. --------------------------------------------------------------------------
  16. Note
  17. -----
  18. - dynamic statistics used: dynamic sampling (level = 2)
  19. Statistics
  20. ----------------------------------------------------------
  21. 0 recursive calls
  22. 0 db block gets
  23. 7 consistent gets
  24. 0 physical reads
  25. 0 redo size
  26. 605 bytes sent via SQL *Net to client
  27. 377 bytes received via SQL *Net from client
  28. 2 SQL *Net roundtrips to / from client
  29. 0 sorts (memory)
  30. 0 sorts (disk)
  31. 3 rows processed
  32. SQL >
  33. SQL > select A from t order by A;
  34. Execution Plan
  35. ----------------------------------------------------------
  36. Plan hash value: 961378228
  37. ---------------------------------------------------------------------------
  38. | Id | Operation | Name | Rows | Bytes | Cost ( %CPU) | Time |
  39. ---------------------------------------------------------------------------
  40. | 0 | SELECT STATEMENT | | 3 | 39 | 4 ( 25) | 00: 00: 01 |
  41. | 1 | SORT ORDER BY | | 3 | 39 | 4 ( 25) | 00: 00: 01 |
  42. | 2 | TABLE ACCESS FULL | T | 3 | 39 | 3 ( 0) | 00: 00: 01 |
  43. ---------------------------------------------------------------------------
  44. Note
  45. -----
  46. - dynamic statistics used: dynamic sampling (level = 2)
  47. Statistics
  48. ----------------------------------------------------------
  49. 26 recursive calls
  50. 0 db block gets
  51. 10 consistent gets
  52. 0 physical reads
  53. 0 redo size
  54. 605 bytes sent via SQL *Net to client
  55. 609 bytes received via SQL *Net from client
  56. 2 SQL *Net roundtrips to / from client
  57. 1 sorts (memory)
  58. 0 sorts (disk)
  59. 3 rows processed
  60. SQL >

3.奇特的全局临时表

 1.分析全局临时表的类型

全局临时表分为两种类型,一种是基于会话的全局临时表(on commit preserve rows),一种是基于事务的全局临时表(on commit delete rows)

创建基于事务和会话的全局临时表


  
  1. SQL >
  2. SQL > show user
  3. USER is "MAXWELLPAN"
  4. SQL >
  5. SQL > drop table t_tmp_session purge;
  6. drop table t_tmp_session purge
  7. *
  8. ERROR at line 1:
  9. ORA -00942: table or view does not exist
  10. SQL > drop table t_tmp_transaction purge;
  11. drop table t_tmp_transaction purge
  12. *
  13. ERROR at line 1:
  14. ORA -00942: table or view does not exist
  15. SQL > create global temporary table t_tmp_session on commit preserve rows as select * from dba_objects where 1 = 2;
  16. Table created.
  17. SQL >
  18. SQL > col table_name format a50
  19. SQL > col tem format a50
  20. SQL > col duration format a50
  21. SQL > select table_name,temporary,duration from user_tables where table_name = 'T_TMP_SESSION';
  22. TABLE_NAME TEM DURATION
  23. -------------------------------------------------- --- --------------------------------------------------
  24. T_TMP_SESSION Y SYS$SESSION
  25. SQL > create global temporary table t_tmp_transaction on commit delete rows as select * from dba_objects where 1 = 2;
  26. Table created.
  27. SQL > select table_name,temporary,duration from user_tables where table_name = 'T_TMP_TRANSACTION';
  28. TABLE_NAME TEM DURATION
  29. -------------------------------------------------- --- --------------------------------------------------
  30. T_TMP_TRANSACTION Y SYS$TRANSACTION
  31. SQL >

上述命令完成了基于会话的全局临时表 T_TMP_SESSION 和基于事务的全局临时表T_TMP_TRANSACTION。接下来大家肯定想知道DML操作针对全局临时表产生的日志和针对普通表有什么不同.

2.观察各类DML的redo量

分别观察两种全局临时表针对各类DML语句产生的redo量


  
  1. create or replace view v_redo_size as
  2. select a.name,b.value
  3. from v$statname a,v$mystat b
  4. where a.statistic# =b.statistic#
  5. and a.name = 'redo size';

  
  1. SQL >
  2. SQL > show user;
  3. USER is "MAXWELLPAN"
  4. SQL > select * from v_redo_size;
  5. NAME VALUE
  6. -------------------- ----------
  7. redo size 240504
  8. SQL > insert into t_tmp_transaction select * from dba_objects;
  9. 73266 rows created.
  10. SQL > select * from v_redo_size;
  11. NAME VALUE
  12. -------------------- ----------
  13. redo size 774580
  14. SQL > select 774580 -240504 from dual;
  15. 774580 -240504
  16. -------------
  17. 534076
  18. SQL > insert into t_tmp_session select * from dba_objects;
  19. 73266 rows created.
  20. SQL > select * from v_redo_size;
  21. NAME VALUE
  22. -------------------- ----------
  23. redo size 1308488
  24. SQL > select 1308488 - 774580 from dual;
  25. 1308488 -774580
  26. --------------
  27. 533908
  28. SQL > update t_tmp_transaction set object_id =rownum;
  29. 73266 rows updated.
  30. SQL > select * from v_redo_size;
  31. NAME VALUE
  32. -------------------- ----------
  33. redo size 7788968
  34. SQL > select 7788968 - 1308488 from dual;
  35. 7788968 -1308488
  36. ---------------
  37. 6480480
  38. SQL > update t_tmp_session set object_id =rownum;
  39. 73266 rows updated.
  40. SQL > select * from v_redo_size;
  41. NAME VALUE
  42. -------------------- ----------
  43. redo size 12430324
  44. SQL > select 12430324 - 7788968 from dual;
  45. 12430324 -7788968
  46. ----------------
  47. 4641356
  48. SQL > delete from t_tmp_session;
  49. 73266 rows deleted.
  50. SQL > select * from v_redo_size;
  51. NAME VALUE
  52. -------------------- ----------
  53. redo size 23330180
  54. SQL > select 23330180 - 12430324 from dual;
  55. 23330180 -12430324
  56. -----------------
  57. 10899856
  58. SQL > delete from t_tmp_transaction;
  59. 73266 rows deleted.
  60. SQL > select * from v_redo_size;
  61. NAME VALUE
  62. -------------------- ----------
  63. redo size 34230036
  64. SQL > select 34230036 - 23330180 from dual;
  65. 34230036 -23330180
  66. -----------------
  67. 10899856
  68. SQL >

全局临时表和普通表产生日志情况的比较


  
  1. SQL >
  2. SQL > drop table t purge;
  3. Table dropped.
  4. SQL > show user;
  5. USER is "MAXWELLPAN"
  6. SQL > create table t as select * from dba_objects where 1 = 2;
  7. Table created.
  8. SQL > select * from v_redo_size;
  9. NAME VALUE
  10. -------------------- ----------
  11. redo size 34301144
  12. SQL > insert into t select * from dba_objects;
  13. 73266 rows created.
  14. SQL > select * from v_redo_size;
  15. NAME VALUE
  16. -------------------- ----------
  17. redo size 45974392
  18. SQL > select 45974392 - 34301144 from dual;
  19. 45974392 -34301144
  20. -----------------
  21. 11673248
  22. SQL > update t set object_id =rownum;
  23. 73266 rows updated.
  24. SQL > select * from v_redo_size;
  25. NAME VALUE
  26. -------------------- ----------
  27. redo size 57139632
  28. SQL > select 57139632 - 45974392 from dual;
  29. 57139632 -45974392
  30. -----------------
  31. 11165240
  32. SQL > delete from t;
  33. 73266 rows deleted.
  34. SQL > select * from v_redo_size;
  35. NAME VALUE
  36. -------------------- ----------
  37. redo size 68186560
  38. SQL > select 68186560 - 57139632 from dual;
  39. 68186560 -57139632
  40. -----------------
  41. 11046928
  42. SQL >

通过简单的比较我们即可得出结论:无论插入、更新还是删除,操作普通表产生的日志都比全局临时表要多。

DML操作针对全局临时表来说,只是产生的日志要少得多,而不是不会产生。

3.全局临时表的两大重要特性

1.高效删除记录

全局临时表有两个重要的特点。一是高效删除记录,基于事务的全局临时表 COMMIT 或者 SESSION 连接退出后,临时表记录自动删除;基于会话的全局临时表则是SESSION连接退出后,临时表记录自动删除,都无须我们手动去操作。二是针对不同会话数据独立,不同的SESSION访问全局临时表,看到的结果不同。

基于事务的全局临时表的高效删除


  
  1. SQL >
  2. SQL > select count( *) from t_tmp_transaction;
  3. COUNT( *)
  4. ----------
  5. 0
  6. SQL > select * from v_redo_size;
  7. NAME VALUE
  8. -------------------- ----------
  9. redo size 68186560
  10. SQL > insert into t_tmp_transaction select * from dba_objects;
  11. 73266 rows created.
  12. SQL > select * from v_redo_size;
  13. NAME VALUE
  14. -------------------- ----------
  15. redo size 68720580
  16. SQL > select 68720580 - 68186560 from dual;
  17. 68720580 -68186560
  18. -----------------
  19. 534020
  20. SQL > commit;
  21. Commit complete.
  22. SQL > select * from v_redo_size;
  23. NAME VALUE
  24. -------------------- ----------
  25. redo size 68720756
  26. SQL > select count( *) from t_tmp_transaction;
  27. COUNT( *)
  28. ----------
  29. 0
  30. SQL >
  31. SQL > select 68720756 - 68720580 from dual;
  32. 68720756 -68720580
  33. -----------------
  34. 176
  35. SQL > ---commit 方式删除全局临时表记录所产生的日志量是176B
  36. SQL >

基于会话的全局临时表COMMIT并不清空记录


  
  1. SQL >
  2. SQL > show user;
  3. USER is "MAXWELLPAN"
  4. SQL > select * from v_redo_size;
  5. NAME VALUE
  6. -------------------- ----------
  7. redo size 68720756
  8. SQL > insert into t_tmp_session select * from dba_objects;
  9. 73266 rows created.
  10. SQL > select * from v_redo_size;
  11. NAME VALUE
  12. -------------------- ----------
  13. redo size 69268792
  14. SQL > select 69268792 - 68720756 from dual;
  15. 69268792 -68720756
  16. -----------------
  17. 548036
  18. SQL > commit;
  19. Commit complete.
  20. SQL > select count( *) from t_tmp_session;
  21. COUNT( *)
  22. ----------
  23. 73266
  24. SQL > select * from v_redo_size;
  25. NAME VALUE
  26. -------------------- ----------
  27. redo size 69268940
  28. SQL > select 69268940 - 69268792 from dual;
  29. 69268940 -69268792
  30. -----------------
  31. 148
  32. SQL >

退出基于事务的全局临时表后再登入,观察记录情况


  
  1. SQL > exit
  2. Disconnected from Oracle Database 19c Enterprise Edition Release 19.0 .0 .0 .0 - Production
  3. Version 19.3 .0 .0 .0
  4. [oracle @oracle -db -19c ~]$ sqlplus / as sysdba
  5. SQL *Plus: Release 19.0 .0 .0 .0 - Production on Thu Jan 5 11: 22: 30 2023
  6. Version 19.3 .0 .0 .0
  7. Copyright (c) 1982, 2019, Oracle. All rights reserved.
  8. Connected to:
  9. Oracle Database 19c Enterprise Edition Release 19.0 .0 .0 .0 - Production
  10. Version 19.3 .0 .0 .0
  11. SQL > connect maxwellpan /maxwellpan @PDB1;
  12. Connected.
  13. SQL > show user;
  14. USER is "MAXWELLPAN"
  15. SQL > select count( *) from t_tmp_session;
  16. COUNT( *)
  17. ----------
  18. 0
  19. SQL >

如果全局临时表在程序的一次调用执行过程中需要多次清空记录再插入记录就要考虑用基于事务的,这时COMMIT可以把结果快速清理了,否则用delete效率低下。如果不存在这种情况,就用基于会话的,更简单,连COMMIT的动作都省了。

一般来说,基于会话的全局临时表的应用会更多一些,少数比较复杂的应用,涉及一次调用中需要清空记录再插入等复杂动作时,才考虑用基于事务的全局临时表。

2.不同会话独立

基于全局临时表的会话独立性的观察——第1个会话


  
  1. SQL > show user;
  2. USER is "MAXWELLPAN"
  3. SQL > select * from v$mystat where rownum = 1;
  4. SID STATISTIC# VALUE CON_ID
  5. ---------- ---------- ---------- ----------
  6. 18 0 0 3
  7. SQL > select * from t_tmp_session;
  8. no rows selected
  9. SQL > insert into t_tmp_session select * from dba_objects;
  10. 73266 rows created.
  11. SQL > commit;
  12. Commit complete.
  13. SQL > select count( *) from t_tmp_session;
  14. COUNT( *)
  15. ----------
  16. 73266
  17. SQL >

基于全局临时表的会话独立性的观察——第2个会话


  
  1. [root @oracle -db -19c ~]# su - oracle
  2. [oracle @oracle -db -19c ~]$
  3. [oracle @oracle -db -19c ~]$ sqlplus / as sysdba
  4. SQL *Plus: Release 19.0 .0 .0 .0 - Production on Thu Jan 5 11: 30: 28 2023
  5. Version 19.3 .0 .0 .0
  6. Copyright (c) 1982, 2019, Oracle. All rights reserved.
  7. Connected to:
  8. Oracle Database 19c Enterprise Edition Release 19.0 .0 .0 .0 - Production
  9. Version 19.3 .0 .0 .0
  10. SQL > connect maxwellpan /maxwellpan @PDB1;
  11. Connected.
  12. SQL > show user;
  13. USER is "MAXWELLPAN"
  14. SQL > select * from v$mystat where rownum = 1;
  15. SID STATISTIC# VALUE CON_ID
  16. ---------- ---------- ---------- ----------
  17. 143 0 0 3
  18. SQL > select count( *) from t_tmp_session;
  19. COUNT( *)
  20. ----------
  21. 0
  22. SQL > insert into t_tmp_session select * from dba_objects where rownum = 1;
  23. 1 row created.
  24. SQL > commit;
  25. Commit complete.
  26. SQL > select count( *) from t_tmp_session;
  27. COUNT( *)
  28. ----------
  29. 1
  30. SQL >

这是一个神奇的特性,结合高效删除,灵活应用这两个特性,将会给相关工作带来巨大的帮助。大家将会在后续的课程中感受到。


转载:https://blog.csdn.net/u011868279/article/details/128547006
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场