1、有一表数据量比较大(200万以上),其中的数据归属于多个模块,我数据按模块号分在多表里。这样搞模块查不同的表应该可以提高效率。但不清楚需要查所有表时用Union是否会效率很低?主要还是希望哪位能说明一下Union的效率问题。2、数据库里的时间类型是整形存储的,那他查找效率是否能和整形一样快?不太清楚时间类型的效率。3、如果一个表的记录需要分多次查询完,用什么来标示上一次查到哪里了?比如查出200万记录,我一次只能处理50条,下一次要查这50条以后的,如何做?我觉得用ROWNUM和ROWID都不好实现,如果给记录加Idx的话也会存在每次查询需要order by Idx,应该会影响效率。是否用常连接不释放可以做到?4、接着上面的问题顺便问下,Oracle有没有自增加字段的用法?就是说一个相当于Idx的字段,每插入一条数据自动帮你写个整数序号5、Oracle中有没有选取随机记录的方法,我以前用MSSQL里有一个select top n * from tablename order by newid()这样可以选随机10条数据。不知道Oracle里有没办法实现随机选取记录?6、在Oracle中一次查询出的结果是否必须全部取完?如果是长连接的连接池,我从池中取一个连接,查询了数据,然后只取了查询结果的前几条。然后释放了连接,是否会对下一次的操作有什么影响?这些问题困扰我好多天了,希望能有高手帮忙解答一下,感谢各位不吝赐教。

解决方案 »

  1.   

    2、只要你字段是date型的都是按date类型来存储的。除非你的字段类型为整型。不清楚整型和date型哪个快。
    3、用游标来实现吧,rowcount;
    4、序列,sequence;
    5、可以,dbms_random函数,具体参见之前的帖子
    select  col1 from (select col1 from t order by dbms_random.value) where rownum<=10
      

  2.   

    1.Union可以拼表,比表内的查询肯定要慢些的。楼主的这种做法可以使用create view,如果数据大了,可以使用create partition来存放和管理。
    2.使用时间类型,一般格式为:yyyy-mm-dd hh24:mi:ss。甚至为邮戳类型,其优点是对数据判断较细,缺点是判断运算时间较长。
    3.使用Oracle的记录内部rownum号,如:select * from tab where rownum<=10;
    4.给个简单的参考例子:create table t(pk number primary key,...); 
    create sequence t_seq; 
    create trigger t_trigger before insert on t for each row 
    begin 
      select t_seq.nextval into :new.pk from dual; 
    end; 
    5.--给你看个使用随机函数(dbms_random)的例子:
    SQL> 
    SQL> select * from tab where rownum<=5;A                 B
    -------- ----------
    0121          60.00
    012101        70.00
    0122         110.00
    0124         230.00
    012303        45.00SQL> select * from tab where rownum<=5 order by  dbms_random.value();A                 B
    -------- ----------
    012101        70.00
    012303        45.00
    0121          60.00
    0124         230.00
    0122         110.00SQL> 
    6.这是Oracle自身考虑的资源申请与释放的问题,Oracle用户可以不必考虑之。
      

  3.   

    1、有一表数据量比较大(200万以上),其中的数据归属于多个模块,我数据按模块号分在多表里。这样搞模块查不同的表应该可以提高效率。但不清楚需要查所有表时用Union是否会效率很低?主要还是希望哪位能说明一下Union的效率问题。
    这一条用分区可以实现,而且便于管理,查所有表的时候也不用union了
    2.看应用情况,如果为了用整数存时间需要进行转换的话那就用date,就是说那种方便用那种,通常建议用date
    3.网上搜一下分页查询
    4.需要自己实现,序列+触发器
    5.select * from (select * from tablename order by sys_guid()) where rownum < N
    6.只要你查询了oracle就会把结果给你取出来,最好是需要多少取多少,取的数据多了会占用内存,I/O等资源,对下次基本没有影响。(个人理解,仅供参考)
      

  4.   

    2楼的5:
    select * from tab where rownum<=5 order by  dbms_random.value();
    明显是错误啊!
    对于大表,取随机数(速度快):
    select * from emp sample(10);  --抽样10%
      

  5.   


    -----》对于1、回答:对于“希望哪位能说明一下Union的效率问题。”,首先应明白Union是连接查询出各表中想要的相关对象信息,在各表关联没有问题的前题下,对于“数据量比较大(200万以上)”的情况下,查询“效率”是取决于查询数据量的多少来决定的,是相对问题。你在PISQL Developer工具的SQL脚本内多作几次测试,在其下方状态栏内会显示出每次查询完所耗的相对时间,你就会明白Union的效率了。-----》对于2、回答:对于“数据库里的时间类型是整形存储的,那他查找效率是否能和整形一样快?”,如果这个”时间类型“都是整形相对是一样快的,对于其它类型就要另当别论。-----》对于3、回答:对于“用常连接不释放可以做到?”是相对于取到的数据集而言,加入到事物处理程序可以做到,但须分步处理,并且取到的数据集是可以存放在本地,可供响应的事件调用它。-----》对于4、回答:对于“相当于Idx的字段,每插入一条数据自动帮你写个整数序号”,给Idx的字段建个序列就可实现自增长。-----》对于5、回答:对于“选取随机记录”可以,EG:在1到17条随机选取记录:   
      select   a.*   from     (select   rownum   rn,a.*   from   t_jg   a)a   where   rn=(select   round(dbms_random.value(1,17))   rn   from   dual);   
        
      随机选出(在1到17条范围内,一条没有,一条,多条)记录   
        select   a.*   from     (select   rownum   rn,a.*   from   t_jg   a)a   where   rn=round(dbms_random.value(1,17)); 
      
    -----》对于6、回答:释放了连接,就不会对下一次的操作有影响,如代事物处理的,commit后就没有影响。
      

  6.   

    感谢各位的回复,我现在理解是这样的:1、Union联表的时间就是各表查询的时间和,与放在一个表中差别不大。对于数据很大的表应该使用分区来管理。对于分区管理的方法还不太懂,不知道有没有哪位能提供一下参考文档。2、可能是我没表达清楚,我想问的是数据库里用时间类型是不是比用整型的效率低很多?(我以前了解的时间类型在数据库里就是用整型实现的,所以有此一问)3、这个应该用分页查询,需要使用到游标吧?不知道哪位能提供点资料或样例。问个弱问题:游标分页查询是否是直接在程序里向数据库传SQL就能实现?还是说必须在数据库提前做一些操作?4、此问题已解决。5、此问题已解决。6、此问题已解决。不知道哪位能再对前面的3个补充一下,感谢。
      

  7.   

    1见21楼:
    http://topic.csdn.net/u/20081107/12/572b3ce9-1560-42bf-bf47-6cc760b405ad.html2.时间类型用date来定义,数字用int或number来定义,替代方法严重影响效率(楼主可能用c语言以前自编过数据库)。3见5楼:
    http://topic.csdn.net/u/20081002/00/f8d90ba2-e2bb-412a-a0c5-1b6d518fc22a.html
      

  8.   


    -----》对于1、回答:在Oracle中对于分区管理可做以下几点去理解:
      1、允许用户将一个表分成多个分区
      2、用户可以执行查询,只访问表中的特定分区
      3、将不同的分区存储在不同的磁盘,提高访问性能和安全性
      4、可以独立地备份和恢复每个分区
      表分区的类型有:范围分区,散列分区,列表分区,复合分区,----诸内容各涉及知识较多,请自己搜索一一理解。-----》对于2、回答:在Oracle中日期时间数据类型存储日期和时间值,使用7个字节固定长度,每个字节分别包括存储世纪年、月、日,小时、分钟、秒
    主要的日期时间类型有:1.DATE - 存储日期和时间部分,精确到整个的秒
                          2.TIMESTAMP - 存储日期、时间和时区信息,秒值精确到小数点后6位。
      另外你须了解一下在Oracle中专业术语是没有‘整型’这一称呼,是称‘数值数据类型’,数值数据类型:可以存储整数、浮点数和实数,最高精度为 38 位。数值数据类型的声明语法:NUMBER [( p[, s])],P表示精度,S表示小数点的位数。相信你结合程序运行的基础知识比较一下,就可知道那种数据类型效率低了。-----》对于3、中“游标分页查询是否是直接在程序里向数据库传SQL就能实现?还是说必须在数据库提前做一些操作?”你须了解一下游标作用流程:它先是从Oracle 服务器--》执行PL/SQL 程序--》通过检索行--》保存到游标中(也就是存储单元)--》提取需要的行--》一次处理一行,逐行处理查询结果,以编程的方式访问数据。
    用游标一次处理一行来达到分页的目的代价也太大了吧!如果每次你都‘查出200万记录’左右的数据记录建议你上GOOGLE搜索一个写在页面内的JavaScript能分页代码会现得恰当些。再讨论就又离问题更远了 。
      

  9.   

    感谢楼上两位的细心解答。1、分区的概念我基本了解了。我的需求是有1到几十个模块不定,想按模块号对5取模的值分成5个区,看了下几种分区,感觉就散列还像我的需求,但显然分5个区的散列算法不是对5取模。请问有没有好的建议?2、shoulder618讲得很清楚了,这个我基本了解了。时间类型效率明显低多了。但是如果建个索引的话应该就不会太低了,应该比7字节的字符串查找还要快些。3、我的需求并非要在网页上显示,而是用户发个查询消息给我,我要将可能查到的0到n条数据按50条一包分包返回,返回通过一个TCP/IP通信发给用户,我需要在每包发送成功后才能发下包。并且用户不只一个,最好能并行处理64个用户的查询,因查询条件不一样,不能复用一个结果集。我现在希望能在代码里通过SQL语句,在数据库中查询生成64个游标,取下一包时接着使用上次的游标。我看很多网上给出例子都是在数据库中建存储过程,我感觉这达不到我想要的效果。我觉得最好能在程序里执行SQL的方式生成游标,并能下次方便的使用。不知道各位高手有没有好的建议?再次感觉各位的帮助
      

  10.   

    对于3如果我用:select * from
    (
    select t_test.*,rownum rn from t_test
    )a
    where a.rn > 本包的开始号 and a.rn < 本包的结束号;应该相当于每包都在查200万数据了,就太慢了。
      

  11.   


    这个不是这样用的,你这个oracle没办法用stop key的执行计划select *
     from 
    (
    select x.*, rownum rn from (select * from t_test) x where rownum <= 结束
    )
    where rn > 开始