Oracle SQL 性能优化技巧整理

    1.用适合的ORACLE化器

     ORACLE化器共有3

     A RULE ( 基于 规则 ) b COST ( 基于成本 ) c CHOOSE ( 选择 )
      置缺省的 化器,可以通 过对 init.ora 文件中 OPTIMIZER_MODE 参数的各 声明,如 RULE COST CHOOSE ALL_ROWS FIRST_ROWS 你当然也在 SQL 或是会 (session) 级对 行覆盖。
      了使用基于成本的 化器 (CBO Cost-Based Optimizer) ,你必 须经 常运行 analyze 命令,以增加数据 中的 统计 信息 (object statistics) 的准确性。
      如果数据 化器模式 为选择 (CHOOSE) ,那 么实际 化器模式将和是否运行 analyze 命令有 如果 table analyze 化器模式将自 CBO 反之,数据 将采用 RULE 形式的 化器。
在缺省情况下, ORACLE 采用 CHOOSE 化器, 了避免那些不必要的全表 (full table scan) 你必 尽量避免 使用 CHOOSE 化器,而直接采用基于 规则 或者基于成本的 化器。
   2. 访问 Table 的方式
      ORACLE 采用两 种访问 表中 记录 的方式:
     A 全表
           全表 描就是 序地 访问 表中 记录 ORACLE 采用一次 入多个数据 (database block) 的方式 化全表 描。
     B
ROWID 访问
           你可以采用基于 ROWID 访问 方式情况,提高 访问 表的效率, ROWID 包含了表中 记录 的物理位置信息。 ORACLE 采用索引 (INDEX) 实现 了数据和存放数据的物理位置 (ROWID) 系。通常索引提供了快速 访问 ROWID 的方法,因此那些基于索引列的 查询 就可以得到性能上的提高。
3. 共享 SQL
      了不重 解析相同的 SQL 句,在第一次解析之后, ORACLE SQL 句存放在内存中。 这块 位于系 全局区域 SGA(system global area) 的共享池 (shared buffer pool) 中的内存可以被所有的数据 共享。 因此,当你 行一个 SQL ( 被称 一个游 ) ,如果它和之前的 完全相同, ORACLE 就能很快 得已 被解析的 句以及最好的 行路径。 ORACLE 个功能大大地提高了 SQL 行性能并 省了内存的使用。
      可惜的是 ORACLE 对简单 的表提供高速 (cache buffering) 个功能并不适用于多表 查询
      数据 管理 init.ora 为这 个区域 置合适的参数,当 个内存区域越大,就可以保留更多的 句,当然被共享的可能性也就越大了。
      当你向 ORACLE 提交一个 SQL 句, ORACLE 会首先在 这块 内存中 找相同的 里需要注明的是, ORACLE 两者采取的是一 种严 格匹配,要达成共享, SQL 句必 完全相同 ( 包括空格, 行等 )
      数据 管理 init.ora 为这 个区域 置合适的参数,当 个内存区域越大,就可以保留更多的 句,当然被共享的可能性也就越大了。
     
共享的 句必 须满 足三个条件:
     A 字符 的比 当前被 行的 句和共享池中的 句必 完全相同。
      B 两个 句所指的 象必 完全相同:
     C 两个 SQL 句中必 使用相同的名字的 (bind variables)
4. 选择 最有效率的表名 ( 只在基于 规则 化器中有效 )
      ORACLE 的解析器按照从右到左的 FROM 子句中的表名,因此 FROM 子句中写在最后的表 ( driving table) 将被最先 理。在 FROM 子句中包含多个表的情况下,你必 须选择记录 条数最少的表作 表。当 ORACLE 理多个表 会运用排序及合并的方式 接它 。首先, 描第一个表 (FROM 子句中最后的那个表 ) 对记录进 行派序,然后 描第二个表 (FROM 子句中最后第二个表 ) ,最后将所有从第二个表中 索出的 记录 与第一个表中合适 记录进 行合并。
      如果有 3 个以上的表 查询 那就需要 选择 交叉表 (intersection table) 表, 交叉表是指那个被其他表所引用的表。
5.WHERE 子句中的
      ORACLE 采用自下而上的 序解析 WHERE 子句,根据 个原理,表之 接必 写在其他 WHERE 条件之前, 那些可以 过滤 掉最大数量 记录 的条件必 写在 WHERE 子句的末尾。
6.SELECT 子句中避免使用 ' * '
      当你想在 SELECT 子句中列出所有的 COLUMN ,使用 动态 SQL 列引用 '*' 是一个方便的方法。不幸的是, 是一个非常低效的方法。 实际 上, ORACLE 在解析的 程中, 会将 '*' 依次 转换 成所有的列名, 个工作是通 过查询 数据字典完成的, 意味着将耗 更多的 时间
7. 减少 访问 数据 的次数
      SQL ORACLE 在内部 行了 多工作:解析 SQL 句,估算索引的利用率, 量, 数据 等等。由此可 ,减少 访问 数据 的次数,就能 实际 上减少 ORACLE 的工作量。
8. 使用 DECODE 函数来减少 时间
      使用 DECODE 函数可以避免重 复扫 描相同 记录 或重 复连 接相同的表。
9. 整合 简单 ,无 关联 的数据 库访问
      如果你有几个 简单 的数据 库查询语 句,你可以把它 整合到一个 查询 ( 即使它 没有 )
10. 除重 复记录
11. TRUNCATE 替代 DELETE
      除表中的 记录时 ,在通常情况下, (rollback segments ) 用来存放可以被恢 的信息。 如果你没有 COMMIT ORACLE 会将数据恢 除之前的状 ( 准确地 是恢 除命令之前的状况 )
      而当运用 TRUNCATE 段不再存放任何可被恢 的信息。当命令运行后,数据不能被恢 。因此很少的 源被 用, 时间 也会很短。
 
12. 尽量多使用 COMMIT
      只要有可能,在程序中尽量多使用 COMMIT 这样 程序的性能得到提高,需求也会因 COMMIT 放的 源而减少
     COMMIT 放的 源:
     A 段上用于恢 数据的信息。
    B 、被程序 得的
     C redo log buffer 中的空
     D ORACLE 管理上述 3 种资 源中的内部花
13. 记录 条数
      和一般的 点相反, count(*) count(1) 稍快,当然如果可以通 索引 索, 索引列的 数仍旧是最快的。例如 COUNT(EMPNO)
14. Where 子句替 HAVING 子句
      避免使用 HAVING 子句, HAVING 只会在 索出所有 记录 之后才 对结 果集 过滤 理需要排序, 总计 等操作。如果能通 WHERE 子句限制 记录 的数目,那就能减少 方面的 开销
 
15. 减少 表的 查询
      在含有子 查询 SQL 句中,要特 注意减少 表的 查询
16. 内部函数提高 SQL 效率。
17. 使用表的 (Alias)
      当在 SQL 句中 接多个表 使用表的 名并把 名前 Column 上。 这样 一来,就可以减少解析的 时间 并减少那些由 Column 引起的 错误
18. EXISTS 替代 IN
      多基于基 表的 查询 中, 足一个条件,往往需要 另一个表 接。在 这种 情况下,使用 EXISTS( NOT EXISTS) 通常将提高 查询 的效率。
19. NOT EXISTS 替代 NOT IN
      在子 查询 中, NOT IN 子句将 行一个内部的排序和合并。 在哪 情况下, NOT IN 都是最低效的 ( 查询 中的表 行了一个全表遍 ) 了避免使用 NOT IN ,我 可以把它改写成外 (Outer Joins) NOT EXISTS
20. 用表 接替 EXISTS
      通常来 采用表 接的方式比 EXISTS 更有效率
21. EXISTS DISTINCT
      当提交一个包含一 多表信息 ( 比如部 表和雇 ) 查询时 ,避免在 SELECT 子句中使用 DISTINCT 一般可以考 EXIST
Oracle 内存 ( )----Process Memory 详细 信息
The Process Memory :
 
除了 SGA(System Global Area) 之外 ,Oracle 使用下面三个全局区 :
  The Process Global Area (
PGA )
  The User Global Area (UGA)
  The Call Global Area (CGA)
  很多人都搞不清楚 PGA UGA 两者之 的区 , 实际 上两者之 的区 跟一个 程和一个会 的区 似的 . 尽管 说进 程和会 一般都是一 一的 , 实际 上比 个更 复杂 . 一个很明 的情况是 MTS 配置 , 往往会比 程多得多 . 这种 配置下 , 一个 程会有一个 PGA , 一个会 会有一个 UGA. PGA 所包含的信息跟会 是无任何 关联 , UGA 包含的信息是以特定的会 话为 .
  The PGA :
  程全局区 ( PGA 即可以理解 ) Process Global Area, 也可以理解 Program Global Area. 它的内存段是在 程私有区 (Process Private Memory 而不是在共享区 (Shared Memory 它是个全局区意味着它包含了所有代 ). ) 有可能 入的全局 量和数据 , 但是它是不被所有 程共享的 . Oracle 的服 程都包含有属于自己的 PGA , 它只包含了本 程的相 特定信息 . PGA 中的 构不需要由 latches 来保 , 其它的 程是不能 入到 里面来 访问 .
  PGA 包含的是有 关进 程正在使用的操作系 统资 源信息以及 程的状 信息 , 而其它的 程所使用的 Oracle 的共享 源是在 SGA . PGA 是私有的而不是共享的 , 个机制是有必要的 , 程死掉后可以把 源清除和 放掉 .
  PGA 包含两个主要区域 :Fixed PGA Variable PGA 或称 PGA Heap. Fixed PGA 的作用跟 Fixed SGA 似的 , 都包含原子 ( 不可分的 ), 小的数据 构和指向 Variable PGA 的指 .
  Variable PGA 是一个堆 . 它的 Chunks 可以从 Fixed Table X$KSMPP 看得到 , 个表的 构跟前面有提到的 X$KSMSP 是相同的 . PGA 包含了一些有 HEAP Fixed Table 的永久性内存 , 它跟某些参数的 置有依 赖关 . 些参数包含 DB_FILES,LOG_FILES,CONTROL_FILES.
  The UGA:
  UGA(User Global Area) 包含的是特定会 的信息 , 有如下一些 :
  所打 的持 和运行 时间 内的区域
  包的状 信息 , 特定的
  Java
  可以用的 ROLES
  ENABLE 的跟踪事件
  起作用的 NLS 参数
  DBLINK
  的入口控制
  PGA ,UGA 也由两区 :Fixed UGA Variable UGA, 也称 UGA HEAP. Fixed UGA 包含了大 70 个原子 , 小的数据 构和指向 Variable UGA 的指 .
  UGA HEAP 中的 Chunks 可以从它 自己的会 中通 过查 看表 X$KSMUP 得相 信息 , 个表的 构跟 X$KSMSP 是一 .UGA HEAP 包含了一些有 fixed tables 的永久性内存段 , 跟一些参数的 置有依 赖关 . 些参数有 OPEN_CURSORS,OPEN_LINKS, MAX _ENABLE_ROLES.
  UGA 在内存中的位置依 于会 的配置方式 . 如果会 话连 接的配置方式是 用服 器模式 (DDS) 即是一个会 话对应 一个 , UGA 是放在 PGA 中的 . PGA ,Fixed UGA 是其中的一个 Chunk, UGA HEAP PGA 的一个子堆 (Subheap). 如果会 话连 接是配置 共享服 器模式 (MTS), Fixed UGA SHARED POOL 中的一个 Chunk, UGA HEAP SHARED POOL 中的子堆 (Subheap)
  The CGA:
  跟其它的全局区不同 ,Call Global Area 是短 性存在的 . 它只有在 用数据期 存在 , 一般是在 对实 例的最低 级别 才需要 CGA, 如下 :
  分析一个 SQL
  行一个 SQL
  取出一个 SELECT 句的
  一个 独的 CGA 递归调 是需要的 . SQL 句的分析 程中 , 数据字典信息的 递归调 用是需要的 , SQL 法分析 , 有在 句的 化期 . PL/SQL 块时 SQL 句的 也是需要 递归调 用的 , DML 句的 理触 行也是需要 递归调 用的 .
  不管 UGA 是放在 PGA 是在 SGA ,CGA 都是 PGA 的一个子堆 (Subheap). 个事 的一个重要推 是在一个 用的期 是一个 . 于在一个 MTS Oracle 数据 库进 开发时关 一点的理解是很重要的 . 如果相 , 就得增加 processes 的数量以适 应调 用的增加 .
  没有 CGA 中的数据 ,CALLS 是没法工作的 . 实际 上跟一次 CALL 的数据 构一般都是放在 UGA , SQL AREA,PL/SQL AREA SORT AREA 都必 UGA , 要在各 CALLS 要一直存在并且可用 . CGA 中所包含的数据 构是要在一次 CALL 束后能 够释 放的 . 例如 CGA 包含了 递归调 用的信息 , 直接 I/O BUFFER 有其它的一些 临时 性的数据 .
  Java Call Memory 也是在 CGA . 一段内存比 Oracle 的其它内存段管理得更密集 . 它分成三个 Space: Stack Space, New Space, Old Space. New Space Old Space 中不再被参考使用的 Chunks, 根据它 在使用期 度及 SIZE 的不同 , 用的 程中将被当成不用的 Chunks 收集起来 .New Space Chunks 很多次的不用的 Chunks 的反 收集 程中没有被收集的 Chunks 将会被放到 Old Space Chunks . 是在 Oracle 内存管理中唯一的一个 物收集 (garbage collection), 其它的 Oracle 内存段都是 Dead Chunks.
  Process Memory Allocation
  SGA 不一 的是 ,SGA 例启 之后 SIZE 就已 是定下来的 , PGA SIZE 是会增 . 使用 malloc() 或者 sbrk() 统调 用来 为进 程增加堆数据段大小而使得 PGA SIZE 的增 .OS 的新虚 内存会被做 PGA HEAP 中的一个新的区被加到 PGA 中来 . 些区一般只几 KB , 如果有需要 ,Oracle 将会 分配上千个区 .
  操作系 统对每 程的堆数据段的增 是有限制的 . 大部分的情况是操作系 的内存参数 行限制 (kernel parameter: MAXDSIZ), 有一些情况它的缺省 是可以以 基准 行修改的 . 于所有的 , 操作系 统对 整个虚 内存也有一个系 全局性的限制 , 个限制跟系 SWAP SPACE . 一旦超 两个限制 ,Oracle 程在 行中会遇到 ORA-4030 错误 .
  ORA-4030 错误 生一般不是因 为每 程的 源限制而是因 SWAP SPACE 不足造成 . 问题 可以使用操作系 的一些 选项 SWAP SPACE 的使用情况 . 另外 , 在一些操作系 ,Oracle 包含了一个工具叫 maxmem, 它可以用来 程可以被分配的堆数据段的最大 SIZE 以及哪一个限制是第一次超 .
  如果 问题 的出 是因 SWAP SPACE 不足 , 而且 换页 作非常 繁而且 , 需要减少系 的虚 内存的使用 , 个可以通 减少 程数也可以通 减少 程的内存限制 . 如果 换页动 作不 繁而且比 , 需要 SWAP SPACE SIZE.
 
Process Memory Deallocation:
  Oracle 堆的增 比它 的收 要来得容易 , 当然它 SIZE 也是可以收 . V$MYSTAT V$SESSTAT 视图 , session 统计 信息 session uga memory session pga memory 别显 示了当前 session UGA PGA 的内存大小 , 包含内部的空 . 统计 信息 session uga memory session pga memory max max 别显 示了在 session 的生存期 所使用 得最大的 UGA 和最大的 PGA .
  UGA PGA 只有在特定的操作后才会收 , 些操作如一次磁 排序的合并操作 , 或者用程序 DBMS_ SESSION .FREE_UNUSED_USER_ MEMORY 放内存 . 只有整个 free heap extent 会被 父堆或者是 程堆数据段 , 所以有一部分的内部 free space 在内存 放后仍然存在于 subheap .
  在大多的操作系 统环 境下 ,Oracle 是不会减少 程堆数据段也不会 放虚 内存并将其返 还给 操作系 . 所以从一个操作系 看中 , 一个 Oracle 程将会把虚 内存 SIZE HWM 而保留着 . 如果有必要 ,Oracle 是会将一些没用的虚 内存 页换页 出去的 . 为这 个原因 , Oracle 程的虚 内存 的操作系 统统计 信息都是很 理解的 . 所以一般用的是 Oracle 内部 统计 信息来代替使用操作系 统计 信息 .
  程序 DBMS_ SESSION 只能在 .FREE_UNUSED_USER_ MEMORY 接是配置 MTS 模式的 用才能使用 . 个最好是少点使用 , 它只 放大的包的 array 量所占用的内存返 还给 Large Pool 或者是 Shared Pool. 一般地 ,UGA HEAP 的内存 应该 首先被 , 可以通 指派新的空 array array 量使用 , 也可以通 过调 用程序 DBMS_ SESSION .RESET_PACKAGE.
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值