zoukankan      html  css  js  c++  java
  • 【oracle】同是选出每个城市最年长女性,not exits 方案和 分析函数rank方案的巨大差距

    以下实验版本:

    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    PL/SQL Release 11.2.0.1.0 - Production

    不保证在其它环境也是同样效果。

    表结构:

    create table customer(
        id number(8),
        name nvarchar2(20),
        gender char(1),
        cityname nvarchar2(20),
        birthday timestamp,
        primary key(id)
    )

    可以使用以下程序给它充值:

    declare 
       g integer;
       c integer;
    begin
    for i in 1..100000 loop
        g:=dbms_random.value(1,0);
        c:=dbms_random.value(1,5);
    
        insert into customer values(i,
                                    dbms_random.string('*',dbms_random.value(6,20)),
                    decode(g,0,'m',1,'f'),
                    decode(c,1,'兴城',2,'绥中',3,'山海关',4,'北戴河',5,'津滨'),
                    DATE'1970-01-01'+i);
    end loop;
    
    commit;
    
    end;
    /

    现在需求是把每个城市最年长女性找出来。

    这个方案不止一种,以下是 not exists 方案:

    select id,name,gender,cityname,to_char(birthday,'yyyy-MM-dd') as birthymd from customer a
    where a.gender='f' and
    not exists
    (
        select null from customer b
        where b.gender='f' and b.cityname=a.cityname and b.birthday<a.birthday
    )

    这个方案只是简单实现需求,其执行起来还是挺费时的:

    SQL> select id,name,gender,cityname,to_char(birthday,'yyyy-MM-dd') as birthymd from customer a
      2  where a.gender='f' and
      3  not exists
      4  (
      5      select null from customer b
      6      where b.gender='f' and b.cityname=a.cityname and b.birthday<a.birthday
      7  );
    
            ID NAME                                     G CITYNAME                                 BIRTHYMD
    ---------- ---------------------------------------- - ---------------------------------------- ----------
             1 XGZLORILKOGWELLJI                        f 山海关                                   1970-01-02
             2 JFMOXKKFDJPSNBNQS                        f 绥中                                     1970-01-03
             3 WKMIILRQAKY                              f 北戴河                                   1970-01-04
            23 MKSREQXPKJTWSK                           f 兴城                                     1970-01-24
            30 ILXYETNXOKXSB                            f 津滨                                     1970-01-31
    
    已用时间:  00: 00: 16.38

    十万数据查询,用时16秒,还是挺长的。

    分组求两端的极值,比较合适的方案是用分析函数rank

    select id,name,gender,cityname,birthymd from (
    select 
    id,name,gender,cityname,to_char(birthday,'yyyy-MM-dd') as birthymd, 
    rank() over (partition by cityname order by birthday) as seq
    from customer
    where gender='f')
    where seq=1
    order by id

    看看这个方案的耗时:

    SQL> select id,name,gender,cityname,birthymd from (
      2  select
      3  id,name,gender,cityname,to_char(birthday,'yyyy-MM-dd') as birthymd,
      4  rank() over (partition by cityname order by birthday) as seq
      5  from customer
      6  where gender='f')
      7  where seq=1
      8  order by id;
    
            ID NAME                                     G CITYNAME                                 BIRTHYMD
    ---------- ---------------------------------------- - ---------------------------------------- ----------
             1 XGZLORILKOGWELLJI                        f 山海关                                   1970-01-02
             2 JFMOXKKFDJPSNBNQS                        f 绥中                                     1970-01-03
             3 WKMIILRQAKY                              f 北戴河                                   1970-01-04
            23 MKSREQXPKJTWSK                           f 兴城                                     1970-01-24
            30 ILXYETNXOKXSB                            f 津滨                                     1970-01-31
    
    已用时间:  00: 00: 00.10

    这个方案秒出,比较结果很明显,就不用看解释计划的cost了。

    --END--

  • 相关阅读:
    软件破解系列之OD中断方法
    C#获取类名为Internet_Explorer_Server控件的内容
    C#重启网卡(支持xp和win7)
    软件开发专业技术名词的解释
    一些软件设计的原则
    AntlrWorks的Open没有反应,安装JDK6即可解决
    向大家推荐《思考中医》,这本书对我来说算是中医启蒙了 无为而为
    面对富裕对于贫穷的几乎是天生傲慢我们要呐喊: 我们并不笨,我们只是穷读新科诺贝尔文学奖得主,奥尔罕·帕慕克作品有感 无为而为
    推荐一本书《罗伯特议事规则(Robert's Rules of Order) 》,也许对于想要参与管理的技术人员来说是很有用的 无为而为
    再次发布一个工作地点在上海的Biztalk专家招聘 无为而为
  • 原文地址:https://www.cnblogs.com/heyang78/p/15368037.html
Copyright © 2011-2022 走看看