木匠的微型博客 Charlie Twitter

    follow me on Twitter

    Wednesday, January 07, 2009

    PL/SQL ADT collection usage比较自定义类型数组与PL/SQL数组的性能

    从今天开始, 木匠开始介绍BASE架构中数据库部分的基础部件.
    有了这些基础准备知识以后, 我们再来谈(big picture)整个画面: 异步处理 和 数据复制.

    PL/SQL 是最好的Oracle数据库数据处理和编程语言, 这里讲讲如何提取数据并放进用户数据类型数组ADT/UDT collection. 我仅知道3种方法, 我们通过一组Benchmark找到每个方法的优缺点,帮助指导实践.

    先写了英文的,然后翻译成中文. 详细初始化设置和Benchmark的代码, 请参考英文版链接, 很多关键字看英文版会更清楚.
    你可以暂时忽略create table里面的list partition分区部分, 以后会用到.

    欢迎提出更多更有效的方法.

    Benchmark方案
    -- -- ---
    * RunStats
    * SQL trace, 推荐使用Christian Antognini的TVD$XTAT trace 分析工具 , 读过TOP的人都知道, ^_^.

    测试结果
    -------
    PL/SQL 内置数组(Associative Array and Nested Table) 是从数据库获取结果集的最省资源的方法.
    但是有些时候,你需要把数组当作表(table),来跑一个查询, 你就必须用到ADT/用户数据类型数组.
    比如:

    Declare
    lt_item_tab item_tab;
    Begin
    select item_name, qty, price from TABLE(lt_item_tab);
    End;


    3种方法 和 他们的优缺点:

    1) 将多个列转换成用户数据类型数组, 成批放进数组.
    优点: 代码简洁.
    缺点: 和第二种方法相比, 多消耗50%的CPU时间; Latch锁数差不多.

    2) 使用multiset, 在SQL里面直接构造出用户数据类型数组, 作为一行/一个单元放进数组.
    优点: 使用较少资源, 在我的测试案例里面, 比第一种方法CPU时间少50%.
    缺点: 代码有点复杂; 在版本10.1中,不支持SQL Returning语法. (明天试一下11.1.0.7).

    3) 成批放进 PL/SQL 内置数组, 然后复制数据到用户数据类型数组.
    优点: 使用较少资源, 67% better than approach 1 in my test case; Latch锁数少一半.
    缺点: PGA内存多一倍, 合乎逻辑, 代码有点复杂, 维护性较差.

    注释: ADT: Abstract Data Type, 也叫作 User Define Datatype.

    鄙人以为, 以上所有代码都很简单, 复杂只是相对而言. 嘻嘻.

    No comments: