http://www.toadworld.com/KNOWLEDGE/KnowledgeXpertforOracle/tabid/648/TopicID/TSQ7/Default.aspx

本文主要说明在应用程序内书写和调优 SQL 语句。假设,你已经知道你应用程序中的哪些 SQL 语句需要注意。事实上,这不太容易。那么,我们如何隔离性能差的 SQL?任何中等大小的应用程序都是由成千上万行代码组成,其中还包含 SQL。一个性能差的应用程序可能就毁在一个语句上。我们从哪里开始?

当涉及 SQL 时,性能不佳有两方面:CPU 密集型语句(CPU-intensive statements)和 I/O 密集型语句(I/O-intensive statements)。

  • 前者很容易定位。所有的操作系统都可以让我们查看 CPU 密集型任务。这些任务可以追溯到一个特定用户,一个特定应用程序模块。 CPU 密集型模块一般都是由较差的代码和/或结构造成,而不是性能差的 SQL。一旦确定模块,你必须试图使之更有效率。一个可能的解决方案是将把某些处理移除程序,让数据库处理(高明点的 SQL,存储对象,内联函数,数组处理等)。
  • 第二个是 I/O 密集型的 SQL 语句。这些语句会导致大量的数据库 I/O(全表扫描,排序,更新等),并以很高代价运行几个小时。从 Oracle 7 开始,解决了 SQL 识别问题。通过查询数据库共享池区域,我们可以很容易确定大多数 I/O 密集型 SQL 语句。

下面 SQL 语句演示了如何确定 I/O 命中率低于 80%的 SQL 语句。这个命中率是,自从 SQL 语句第一次被解析到共享池,通过所有执行的语句反应整体 I/O。下面可能是最近几分钟或几天的结果:

SELECT executions,
   2        disk_reads, 
   3        buffer_gets,
   4        ROUND((buffer_gets - disk_reads) / buffer_gets, 2) hit_ratio,
   5        sql_text
   6     FROM   v$sqlarea
   7    WHERE  executions  > 0
   8     AND    buffer_gets > 0
   9     AND    (buffer_gets - disk_reads) / buffer_gets < 0.80
   10   order by 4 desc ;
 
EXECUTIONS DISK_READS BUFFER_GETS  HIT_RATIO SQL_TEXT
---------- ---------- ----------- ---------- -----------------------------------------------------------------------
        16        180         369        .51 SELECT SKU,PREPACK_IND,CASE_ID,TRANSFER_QTY,UNIT_COST,UNIT_RETAIL,ROWID
                                             FROM TSF_DETAIL WHERE transfer = :1  order by sku
        16        30          63         .52 SELECT TRANSFER,TO_STORE,TO_WH FROM TSFHEAD  WHERE TRANSFER = :b1  AND
                                             TRANSFER_STATUS = 'A'
        2         3           7          .57 SELECT SKU   FROM UPC_EAN  WHERE UPC = :b1
        12        14          35         .60 SELECT SUBSTR(DESC_UP,1,30),DEPT,SYSTEM_IND   FROM DESC_LOOK  WHERE
                                             SKU = :b1
        14        13          35         .63 SELECT UNIT_COST,UNIT_RETAIL,SUBCLASS FROM WIN_SKUS WHERE SKU = :b1

相关文章: