• 有关临时表


      临时表本身很占开销:建立数据备份、以及临时表创建索引,都是开销较大的。其优点是对数据的规整、拼接功能强大。在利用临时表的时候,需要取长补短,避免由于使用不当引起的性能问题。

      下示例,业务是“只存放回报中存在的客户、交易编码的上日持仓记录”,原来的实现是:

      

    1、    创建临时表
    create table tempdb..file_seat_done (
        jour_no numeric(10,0) identity,     --    处理编号
        tx_date    char(8),     --    成交日期
        exch_done_no varchar(16),     --    交易所成交序号
        exch_code char,     --    交易所
        seat_no    varchar(10),     --    席位号
        cust_no    varchar(16),     --    客户号
        cust_name varchar(8),    --     客户名称 20061222 6.4.0.2
        tx_no varchar(16),     --    交易编码
        vari_code varchar(8),     --    品种
        deliv_date char(8),     --    交割期
        done_price numeric(19,4),     --    成交价格
        done_qty int,     --    成交手数
        bs_flag    char,     --    买卖标志
        sh_flag    char,     --    投保标志
        eo_flag    char,     --    开平标志
        done_time char(8),     --    成交时间
        note varchar(80),    --   导入时出错信息
        err_flag char(1),    -- 错误单标志
        type_flag char(1),   -- 强减标志
        sys_no varchar(16),    --系统号 20070423 6.4.0.3
        file_id    int,    -- jq 20090107 增加文件编号字段
        order_way    char(1) null,    --下单方式 20090508 6.8.0.1
        order_id    varchar(14) null,    --报单号    20100804 6.8.4.1
        exch_seat_no    varchar(14) null    --交易所席位号    20100804 6.8.4.1
        )
    2、    插入临时表数据
    insert into tempdb..file_seat_done
    select
        tx_date        ,     --    成交日期
        case eo_flag when '0' then min(exch_done_no)    -- 开仓则取最小成交序号
            else max(exch_done_no) end as exch_done_no,     --    交易所成交序号
        exch_code    ,     --    交易所
        seat_no        ,     --    席位号
        cust_no        ,     --    客户号
        ''        ,     --    客户名称 20061222 6.4.0.2
        tx_no        ,     --    交易编码
        vari_code    ,     --    品种
        deliv_date    ,     --    交割期
        done_price    ,     --    成交价格
        sum(done_qty) as done_qty    ,     --    成交手数
        bs_flag        ,     --    买卖标志
        sh_flag        ,     --    投保标志
        eo_flag        ,     --    开平标志
        case eo_flag when '0' then min(done_time)    -- 开仓则取最小成交时间
            else max(done_time) end as done_time,     --    成交时间
            note,             --   导入时出错信息
        err_flag,          -- 错误单标志
        type_flag,    -- 强减标志
        sys_no,        --系统号 20070423 6.4.0.3
        file_id,    -- jq 20090107 增加文件编号字段
        order_way,    --下单方式 20090508 6.8.0.1
        case eo_flag when '0' then min(order_id)
            else max(order_id) end as order_id,        --报单号 20100804 6.8.4.1
        case eo_flag when '0' then min(exch_seat_no)
            else max(exch_seat_no) end as exch_seat_no    --交易所席位号 20100804 6.8.4.1
    from tempdb..temp_seat_done
    where err_flag = '0'
    group by tx_date, exch_code, seat_no, cust_no, tx_no, vari_code, deliv_date,
        done_price, bs_flag, sh_flag,eo_flag,  note,err_flag, type_flag, order_way    --下单方式 
    order by tx_date, eo_flag,exch_code,seat_no,bs_flag,cust_no,vari_code,deliv_date,exch_done_no
    3、    具体业务:只存放回报中存在的客户、交易编码的上日持仓记录
    -- 只存放回报中存在的客户、交易编码的上日持仓记录
    insert into file_cust_hold
    select
        a.tx_date    ,     --    成交日期
        a.exch_code,     --    交易所
        a.seat_no    ,     --    席位号
        a.cust_no    ,     --    客户号
        a.tx_no    ,     --    交易编码
        a.vari_code,     --    品种
        a.deliv_date,     --    交割期
        sum(a.open_hand) as hold_qty,     --    持仓手数
        a.bs_flag    ,     --    买卖标志
        a.sh_flag    ,     --    投保标志
        '1' as yt_flag     --    今仓昨仓标志('1':昨仓,'3':今仓)
    from cust_hold a
    where a.tx_date = (select b.max_date from tempdb..seat_maxdate b
                    where a.exch_code = b.exch_code
                    and a.seat_no = b.seat_no)
    and exists (select * from tempdb..file_seat_done c
                where a.exch_code = c.exch_code
                and a.seat_no = c.seat_no
                and a.cust_no = c.cust_no
                and a.vari_code = c.vari_code
                and a.deliv_date = c.deliv_date)
    group by a.tx_date, a.exch_code, a.seat_no, a.cust_no, a.tx_no,
    a.vari_code, a.deliv_date, a.bs_flag, a.sh_flag
    order by a.cust_no, a.tx_no, a.vari_code, a.deliv_date, a.bs_flag, a.sh_flag

    优化后

    1、    创建临时表时,增加一个“上日结算日”字段
    create table tempdb..file_seat_done (
        jour_no numeric(10,0) identity,     --    处理编号
        tx_date    char(8),     --    成交日期
        exch_done_no varchar(16),     --    交易所成交序号
        exch_code char,     --    交易所
        seat_no    varchar(10),     --    席位号
        cust_no    varchar(16),     --    客户号
        cust_name varchar(8),    --     客户名称 20061222 6.4.0.2
        tx_no varchar(16),     --    交易编码
        vari_code varchar(8),     --    品种
        deliv_date char(8),     --    交割期
        done_price numeric(19,4),     --    成交价格
        done_qty int,     --    成交手数
        bs_flag    char,     --    买卖标志
        sh_flag    char,     --    投保标志
        eo_flag    char,     --    开平标志
        done_time char(8),     --    成交时间
        note varchar(80),    --   导入时出错信息
        err_flag char(1),    -- 错误单标志
        type_flag char(1),   -- 强减标志
        sys_no varchar(16),    --系统号 20070423 6.4.0.3
        file_id    int,    -- jq 20090107 增加文件编号字段
        order_way    char(1) null,    --下单方式 20090508 6.8.0.1
        order_id    varchar(14) null,    --报单号    20100804 6.8.4.1
        exch_seat_no    varchar(14) null,    --交易所席位号    20100804 6.8.4.1
        last_settle_date varchar(8) -- jq 20120702 优化效率,增加上日结算日字段,关联的时候可以少关联一张表
        )
    2、    插入临时表,对于新增字段来说,这次插入并没有源数据,所以填空
    insert into tempdb..file_seat_done
    select
        tx_date        ,     --    成交日期
        case eo_flag when '0' then min(exch_done_no)    -- 开仓则取最小成交序号
            else max(exch_done_no) end as exch_done_no,     --    交易所成交序号
        exch_code    ,     --    交易所
        seat_no        ,     --    席位号
        cust_no        ,     --    客户号
        ''        ,     --    客户名称 20061222 6.4.0.2
        tx_no        ,     --    交易编码
        vari_code    ,     --    品种
        deliv_date    ,     --    交割期
        done_price    ,     --    成交价格
        sum(done_qty) as done_qty    ,     --    成交手数
        bs_flag        ,     --    买卖标志
        sh_flag        ,     --    投保标志
        eo_flag        ,     --    开平标志
        case eo_flag when '0' then min(done_time)    -- 开仓则取最小成交时间
            else max(done_time) end as done_time,     --    成交时间
            note,             --   导入时出错信息
        err_flag,          -- 错误单标志
        type_flag,    -- 强减标志
        sys_no,        --系统号 20070423 6.4.0.3
        file_id,    -- jq 20090107 增加文件编号字段
        order_way,    --下单方式 20090508 6.8.0.1
        case eo_flag when '0' then min(order_id)
            else max(order_id) end as order_id,        --报单号 20100804 6.8.4.1
        case eo_flag when '0' then min(exch_seat_no)
            else max(exch_seat_no) end as exch_seat_no,    --交易所席位号 20100804 6.8.4.1
        ''        -- jq 20120702 补上默认值
    from tempdb..temp_seat_done
    where err_flag = '0'
    group by tx_date, exch_code, seat_no, cust_no, tx_no, vari_code, deliv_date,
        done_price, bs_flag, sh_flag,eo_flag,  note,err_flag, type_flag, order_way    --下单方式 20090508 6.8.0.1
    order by tx_date, eo_flag,exch_code,seat_no,bs_flag,cust_no,vari_code,deliv_date,exch_done_no
    3、    创建索引,为下面的表关联作准备
    create index tmp_i_0 on tempdb..file_seat_done (exch_code,seat_no,cust_no,vari_code,deliv_date) -- jq 20120702 为优化增加索引
    4、    将tempdb..file_seat_done的“上日结算日”字段更新正确
    update    tempdb..file_seat_done
    set    a.last_settle_date = b.max_date
    from    tempdb..file_seat_done a,tempdb..seat_maxdate b
    where    a.exch_code = b.exch_code
    and    a.seat_no = b.seat_no
    5、    为关联方便,在创建第2个索引
    create index tmp_i_2 on tempdb..file_seat_done (last_settle_date,exch_code,seat_no,cust_no,vari_code,deliv_date)
    6、    2表关联,获得业务所需的持仓:只存放回报中存在的客户、交易编码的上日持仓记录
    insert into file_cust_hold
    select
        a.tx_date    ,     --    成交日期
        a.exch_code    ,     --    交易所
        a.seat_no    ,     --    席位号
        a.cust_no    ,     --    客户号
        a.tx_no        ,     --    交易编码
        a.vari_code    ,     --    品种
        a.deliv_date    ,     --    交割期
        sum(a.open_hand) as hold_qty,     --    持仓手数
        a.bs_flag    ,     --    买卖标志
        a.sh_flag    ,     --    投保标志
        '1' as yt_flag     --    今仓昨仓标志('1':昨仓,'3':今仓)
    from cust_hold a,tempdb..file_seat_done c
    where    a.tx_date = c.last_settle_date
                and a.exch_code = c.exch_code
                and a.seat_no = c.seat_no
                and a.cust_no = c.cust_no
                and a.vari_code = c.vari_code
                and a.deliv_date = c.deliv_date
    group by a.tx_date, a.exch_code, a.seat_no, a.cust_no, a.tx_no,
            a.vari_code, a.deliv_date, a.bs_flag, a.sh_flag
    order by a.cust_no, a.tx_no, a.vari_code, a.deliv_date, a.bs_flag, a.sh_flag

    改进之后的方法,主要改进了两点:

    1、  改3表关联为2表关联

    2、  2表关联的时候,总是能使用到索引

  • 相关阅读:
    PATA 1071 Speech Patterns.
    PATA 1027 Colors In Mars
    PATB 1038. 统计同成绩学生(20)
    1036. 跟奥巴马一起编程(15)
    PATA 1036. Boys vs Girls (25)
    PATA 1006. Sign In and Sign Out (25)
    读取web工程目录之外的图片并显示
    DOS命令
    java连接oracle集群
    servlet
  • 原文地址:https://www.cnblogs.com/xiaohengheng/p/6625571.html
Copyright © 2020-2023  润新知