目录
一、查询描述
二、流程分析
1. PGA(Program Global Area)
PGA 主要用于存储与 Oracle 会话和服务器进程相关的私有数据。用户访问首先在 PGA 中进行处理。
-
会话信息:首先,获取和存储会话的特定信息,例如客户端会话变量、会话统计信息和连接信息。
-
排序操作:如果 SQL 语句包含 ORDER BY 等排序操作,PGA 中会分配内存用于排序处理。排序操作会优先在 PGA 的排序区内存中完成。如果排序数据量超过 PGA 可用内存,超出的部分将写入临时表空间。
2. 共享池(Shared Pool)
共享池是系统全局区(SGA, System Global Area)的一部分,主要用于存储和管理 SQL 语句的解析、执行计划以及其他与数据库操作相关的共享信息。PGA 信息处理后,请求进入共享池。
-
Hash 检查:对 SQL 语句生成 Hash 值,检查库缓存1中是否存在该 Hash 值。
- 如果存在,执行软解析。
- 如果不存在,或者相关对象已改变,执行硬解析。
-
软解析:复用已有的解析结果和执行计划,不需要重新解析和生成执行计划。
-
硬解析:库缓存未命中时,执行以下步骤:
- 语法检查:验证 SQL 语句的语法是否正确。
- 语义检查:确认 SQL 语句引用的对象存在且用户具有访问权限。
- 执行计划生成:创建最优的 SQL 执行计划。
- 缓存执行计划:将新的解析结果和执行计划存入共享池的库缓存,以便后续使用。
3. 数据缓存区(Database Buffer Cache)
数据缓存区是内存结构的一部分,用于存储最近访问的数据库数据块。当用户发出 SQL 查询请求时,如果数据块已在缓存中,Oracle 可以直接从内存中读取数据,大大提升性能。共享池解析 SQL 后,数据查询请求会进入数据缓存区。
-
检查数据缓存区:执行解析并生成执行计划后,Oracle 检查所需数据块是否在缓存中,这通过缓存查找完成。
-
命中缓存:如果数据块在缓存中,Oracle 直接从缓存返回数据。
-
未命中缓存:如果缓存中没有所需数据块,Oracle 将从数据文件中读取数据。
4. 数据文件(Data Files)
如果数据缓存区没有命中所需数据块,Oracle 会从数据文件中读取。
-
用户进程 I/O:用户进程从数据文件中读取所需数据块,并将其写入数据缓存区,然后从缓存区返回数据给用户。
-
DBWR 进程写回:如果数据缓存区空间不足,DBWR(Database Writer)进程将部分脏数据(已修改但未写入磁盘的数据块)写回数据文件,为新的数据块腾出空间。
库缓存
库缓存存储解析过的 SQL 语句、PL/SQL 代码块、游标信息以及相应的执行计划。当一个新的 SQL 语句到达时,Oracle 首先会在库缓存中查找该 SQL 的解析结果。查找是通过 SQL 语句的文本哈希值(Text Hash Value)来进行的。如果找到相同的哈希值,说明这条 SQL 语句之前已经被解析过,可以直接使用已有的解析结果和执行计划。 ↩︎