oracle 走索引 为什么增加io

oracle 走索引 为什么增加io,第1张

IO当然包括了读、写两部分,先介绍Oracle中写 *** 作的产生。

1.1 写

介绍写 *** 作之前,先简单的看下Oracle的物理结构:oracle的物理文件包括以下三种文件:控制文件(Control Files)、重做日志文件(Redo Log Files)、数据文件(datafiles)。而数据文件中,根据功能的不同,还可以分为系统数据文件、临时空间文件、回滚段文件和用户数据文件。另外,如果数据库的Archive Log模式被激活,还存在归档日志文件。Oracle的IO产生,就是对这些文件的数据读、写 *** 作。下面再详细看下几种主要写 *** 作的产生及其过程。

1.1.1 控制文件

控制文件中记录了整个数据库的物理结构信息,如数据库名字、数据文件及日志文件名字和位置、事件戳信息等等。任何数据库的结构变化信息,以用于数据恢复,因此数据文件上的SCN变化后,Oracle也会相应修改控制文件上的SCN信息。

1.1.2 用户数据修改

由于内存的读写效率比磁盘的读写效率高万倍,因此,为了降低IO wait,oracle会将数据cache在内存中,对数据的读写尽量在内存中完成。当Buffer Cache中的数据缓存块被修改过了,它就被标记为“脏”数据。根据LRU(Least Recently Used)算法,如果一个数据块最近很少被使用,它就称为“冷”数据块。进程DBWn(系统中可以存在多个DBW进程,n为序号)负责将“冷”的“脏”数据写入数据文件中去。DBWn进程会在以下两种情况下将“脏”数据写入磁盘中去:

当服务进程扫描一定数量(阀值)的Buffer Cache后还没有找到干净、可重用的缓存块后,它会通知DBWn进程将“脏”数据写入文件中去,以释放出空闲缓存;当发生检查点(Checkpoint)时。

1.1.3 Redo Log

在非直接写(Direct Write)的情况下,事务中的写 *** 作都会产生Redo Log,作为数据块异常关闭时的恢复记录。同样,和写用户数据类似,Redo Log也不会被直接写入Redo Log文件,而是先写入Log Buffer中。

Log Buffer是一个可以循环重用的缓存区。LGWR进程负责将Log Buffer中的记录写入Redo Log File中去。一旦Log Buffer中的条目被写入了Redo Log文件中,就可以被重用了。

为了保证事务尽快获得Log Buffer,LGWR进程一般会尽快将Log Buffer中的数据写入Redo Log文件中去。在以下几种情况下,LGWR回将一个连续的Log Buffer写入Redo Log文件中去:

当一个事务提交(COMMIT)时;

每3秒钟写一次Log Buffer;

当Log Buffer到达1/3满时;

当DBWn进程将“脏”数据写入磁盘时;

1.1.4 Archive Log

当据库的Archive Log模式被激活后,所有Redo Log数据都会被写入Archive Log文件中以便日后进行恢复。当发生日志组切换时,ARCn(Archive进程,可以存在多个)进程就会Redo Log文件拷贝到指定存储目录中去,成为Archive Log文件。

1.1.5 临时表空间

当Oracle在执行一些SQL时,会需要一些临时空间来存储执行语句时产生的中间数据。这些临时空间由Oracle从指定的临时表空间中分配给进程。主要有三种情况会占用临时空间:临时表/索引 *** 作、排序和临时LOB *** 作。

临时表/索引

在会话中,当第一次对临时表进行INSERT(包括CTAS)时,Oracle会从临时表空间中为临时表及其索引分配临时空间一存储数据。

排序

任何会使用到排序的 *** 作,包括JOIN、创建(重建)INDEX、ORDER BY、聚合计算(GROUP BY)以及统计数据收集,都可能使用到临时表空间。

排序 *** 作首先会选择在内存中的Sort Area进行(Sort In Memory),一旦Sort Area不足,则会使用临时空间进行排序 *** 作(Sort In Disk)。看以下例子:

SQL>alter session set sort_area_size = 10000000Session altered.

SQL>select owner, object_name from t_test12 order by object_id

47582 rows selected.

Execution Plan

----------------------------------------------------------Plan hash value: 1312425564

------------------------------------------------------------------------------| Id | Operation | Name| Rows | Bytes | Cost (%CPU)| Time |------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 47582 | 1486K| 155 (4)| 00:00:02 || 1 | SORT ORDER BY | | 47582 | 1486K| 155 (4)| 00:00:02 || 2 | TABLE ACCESS FULL| T_TEST1 | 47582 | 1486K| 150 (1)| 00:00:02 |------------------------------------------------------------------------------Statistics

----------------------------------------------------------1 recursive calls

0 db block gets

658 consistent gets

0 physical reads

0 redo size

1566184 bytes sent via SQL*Net to client35277 bytes received via SQL*Net from client3174 SQL*Net roundtrips to/from client

1 sorts (memory)

0 sorts (disk)

47582 rows processed

SQL>alter session set sort_area_size = 10000Session altered.

SQL>select owner, object_name from t_test12 order by object_id

47582 rows selected.

Execution Plan

----------------------------------------------------------Plan hash value: 1312425564

--------------------------------------------------------------------------------| Id | Operation | Name| Rows | Bytes |TempSpc| Cost (%CPU)| Time|--------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 47582 | 1486K| | 1251 (1)| 00:00:16 |

| 1 | SORT ORDER BY | | 47582 | 1486K| 4136K| 1251 (1)| 00:00:16 |

| 2 | TABLE ACCESS FULL| T_TEST1 | 47582 | 1486K| | 150 (1)| 00:00:02 |

---------------------------------------------------------------------------------Statistics

----------------------------------------------------------6 recursive calls

20 db block gets

658 consistent gets

629 physical reads

0 redo size

1566184 bytes sent via SQL*Net to client35277 bytes received via SQL*Net from client3174 SQL*Net roundtrips to/from client

0 sorts (memory)

1 sorts (disk)

47582 rows processed

临时LOB对象

LOB对象包括BLOB、CLOB、NCLOB、和BFILE。在PLSQL程序块中,如果定义了LOB变量,则这些LOB变量就是临时LOB对象。临时LOB对象被创建在临时表空间上,直到LOB数据被释放,或者会话结束。

1.1.6 回滚段

我们知道,一个事务在未被提交前,其做的任何修改都是可以被回滚(Rollback)的。这些回滚数据就被放到回滚段(Rollback Segment)上。此外,一致性读(Read Consistency)、数据库恢复(Recover)都会用到回滚段。

任何数据块的修改都会被记录在回滚段中,甚至Redo Log也会产生回滚记录。当任何一个非只读(只有查询)的事务开始时,oracle会自动为其指定下一个可用的回滚段。事务中任何数据变化都被写入回滚段中。如果事务回滚,oracle根据回滚段中的回滚记录将buffer cache中的“脏”数据恢复,释放回滚段空间。当事务被提交,由于要保证一致性读,oracle并不会立即释放回滚段中的数据,而是会保留一段时间。

1.1.7 Direct-Path Insert

这里,我们还要介绍一种特殊的写 *** 作——Direct-Path Insert(直接路径插入)。Direct-Path Insert通过直接在表中已存在的数据后面添加数据,直接将数据写入数据文件中,而忽略掉了Buffer Cache。

我们前面提到,为了能在意外时恢复数据,每一个数据修改都会被记录到Redo Log中。然而,由于Redo Log需要写入到物理文件中去,是一个比较消耗性能的 *** 作。为了提高性能,我们在批量写入数据时就可以通过Direct-Path Insert的指定NOLOGING的方式来避免写Redo Log。

有多种方法可以指定Direct-Path Insert:CTAS(CREATE TABLE AS SELECT);SQL*Loader指定Direct参数;在语句中指定APPEND提示。

1.2.1 物理读

产生物理读主要有以下几种情况:

? 第一次读取

当数据块第一次被读取到,Oracle 会先将其从磁盘上读入Buffer Cache 中,并将他们放在LRU(Last Recently Used)链表的MRU(Most Recently Used)端。再次访问数据块时就可以直接从Buffer Cache 中读取、修改了。看以下例子:

SQL>select owner, index_name from t_test32856 rows selected.

Execution Plan

----------------------------------------------------------Plan hash value: 2878488296

-----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2856 | 68544 | 22 (0)| 00:00:01 || 1 | TABLE ACCESS FULL| T_TEST3 | 2856 | 68544 | 22 (0)| 00:00:01 |-----------------------------------------------------------------------------Statistics

----------------------------------------------------------407 recursive calls

32 db block gets

344 consistent gets

89 physical reads

0 redo size

103888 bytes sent via SQL*Net to client

2475 bytes received via SQL*Net from client192 SQL*Net roundtrips to/from client

9 sorts (memory)

0 sorts (disk)

2856 rows processed

SQL>select owner, index_name from t_test32856 rows selected.

Elapsed: 00:00:00.03

Execution Plan

----------------------------------------------------------Plan hash value: 2878488296

-----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2856 | 68544 | 22 (0)| 00:00:01 || 1 | TABLE ACCESS FULL| T_TEST3 | 2856 | 68544 | 22 (0)| 00:00:01 |-----------------------------------------------------------------------------Statistics

----------------------------------------------------------0 recursive calls

0 db block gets

276 consistent gets

0 physical reads

0 redo size

103888 bytes sent via SQL*Net to client

2475 bytes received via SQL*Net from client192 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

2856 rows processed

? 数据块被重新读入Buffer Cache

如果有新的数据需要被读入Buffer Cache 中,而Buffer Cache 又没有足够的空闲空间,Oracle 就根据LRU 算法将LRU 链表中LRU 端的数据置换出去。当这些数据被再次访问到时,需要重新从磁盘读入。

SQL>select owner, table_name from t_test22 where owner = 'SYS'

718 rows selected.

Execution Plan

----------------------------------------------------------Plan hash value: 1900296288

--------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 99 | 2178 | 10 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| T_TEST2 | 99 | 2178 | 10 (0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | T_TEST2_IDX1 | 99 | | 1 (0)| 00:00:01 |

--------------------------------------------------------------------------------Predicate Information (identified by operation id):

---------------------------------------------------2 - access("OWNER"='SYS')

Statistics

----------------------------------------------------------0 recursive calls

0 db block gets

145 consistent gets

0 physical reads

0 redo size

21690 bytes sent via SQL*Net to client

902 bytes received via SQL*Net from client49 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

718 rows processed

SQL>select * from t_test1--占用Buffer Cache47582 rows selected.

Execution Plan

----------------------------------------------------------Plan hash value: 1883417357

-----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 47582 | 3996K| 151 (2)| 00:00:02 || 1 | TABLE ACCESS FULL| T_TEST1 | 47582 | 3996K| 151 (2)| 00:00:02 |-----------------------------------------------------------------------------Statistics

----------------------------------------------------------195 recursive calls

0 db block gets

3835 consistent gets

5 physical reads

0 redo size

5102247 bytes sent via SQL*Net to client

35277 bytes received via SQL*Net from client3174 SQL*Net roundtrips to/from client

5 sorts (memory)

0 sorts (disk)

47582 rows processed

SQL>select owner, table_name from t_test22 where owner = 'SYS'

718 rows selected.

Execution Plan

----------------------------------------------------------Plan hash value: 1900296288

连接数据库提示异常的话,是需要重新连接数据库才可以的,重新启动一下。

定律是为实践和事实所证明,反映事物在一定条件下发展变化的客观规律的论断。定律是一种理论模型,它用以描述特定情况、特定尺度下的现实世界,在其它尺度下可能会失效或者不准确。

没有任何一种理论可以描述宇宙当中的所有情况,也没有任何一种理论可能完全正确。人生同样有其客观规律可循。

一、生活定律 痛苦定律:死无疑是痛苦的,然而还有比死更痛苦的东西,那就是等死。

幸福定律:如果你不再总是想着自己是否幸福时,你就获得幸福了。

错误定律:人人都会有过失,但是,只有重复这些过失时,你才犯了错误。

沉默定律:在辩论时,沉默是一种最难驳倒的观点。

动力定律:动力往往只是起源于两种原因:希望,或者绝望。

受辱定律:受辱时的唯一办法是忽视它,不能忽视它时就藐视它如果连藐视它也不能,那么你就只能受辱了。

愚蠢定律:愚蠢大多是在手脚或舌头运转得比大脑还快的时候产生的。

化妆定律:在修饰打扮上花费的时间有多少,你就需要掩饰的缺点也就有多少。

省时定律:要想学会最节省时间的办法,首先就需要学会说"不"。

地位定律:有人站在山顶上,有人站在山脚下,虽然所处的地位不同,但在两者的眼中所看到的对方,却是同样大小的。

失败定律:失败并不以为着浪费时间与生命,却往往意味着你又有理由去拥有新的时间与生命了。

谈话定律:最使人厌烦的谈话有两种:从来不停下来想想或者,从来也不想停下来。

误解定律:被某个人误解,麻烦并不大被许多人误解,那麻烦就大了。

结局定律:有一个可怕的结局,也比不上没有任何结局可怕。

二、工作定律

安全定律:最安全的单位几十年没有得过安全奖(最安全证明你们安全没有做工作)

需要定律:同样两个相同的单位,同样的办公费。多少年以后,发生了变化(证明你们单位办公不需要那么多的钱)出来反对,这种成功的概论会归结为零。

评比定律:领导认为谁好,谁就好。(只要领导看你不顺眼,再辛辛苦苦地工作也是白费力气。)

一票否决定律:在一个单位,比如升工资,比如提拔任用,一个人提出来,往往成功的概率最大,而另一个人站

接受教育定律:每个单位都有吊儿郎当不好好干工作的人。但领导往往在批评这些人的时候,这些人恰恰不在场,于是,便出现了遵纪守法的人,经常接受教育的尴尬局面。

哭闹定律那个部门没有几个因为经常的哭闹而得到了实惠,他有什么理由不经常哭闹下去。(此定理也适用那些经常在领导面前叫苦叫累的部门)

能者多劳定律:在同一科室里,有的人虽然在其岗,但却不能胜任本职工作,那他的工作只能由能胜任该项工作的人去代劳。

不平衡定律:年年当先进的部门或个人,一年没有当先进便想不通从未当先进的部门或个人,当上先进后便想不到。

少劳多得定律:一般的单位,都分为合同工、(过去称为正式工)协议工、临时工等等。拿钱越少的工作量越大,而且越容易被解雇拿钱越多的越没有多少事情可干,而且最不容易被解雇。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/6930799.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-30
下一篇 2023-03-30

发表评论

登录后才能评论

评论列表(0条)

保存