几张表关联查询出一个结果集a,怎么对a操作,才能在同一存储过程中多次使用a,而不是每用到一次,就进行一次关联查询。
不太清楚你具体怎么使用,我能想到这样的解决方案:
1.如果查询结果变动不频繁,可以新建一张表做冗余处理;2.使用缓存技术,把查询结果存入缓存,目的也是减少数据库压力和减少处理时间从而达到优化。3.使用待缓存的数据库连接工具,像hibernate等。
查询结果会变动的,并且操作层面只涉及oracle.原想用with as 但with as 只能使用一次 ,因为关联查询语句太长,逻辑较复杂,如果存储过程中,用到5次该结果集,就写五次查询语句,显得语句繁琐冗余,想过建表,但想着应该有更好的处理方式
@Yesdito:我的理解是这样的:当你执行sql语句,在sql执行完成后,数据库将执行结果返回给你,到这里数据库的操作已经完成,也就是不管Oracle内部自己的缓存还是别的技术支持,数据库只会返回一次结果集给你。如果想要重复使用结果集只能通过别的方式来完成,我们假设Oracle会返回多次结果集,那么会遇到更多的问题:1.以什么机制判断一次返回结果集?2.以什么机制判断返回结果集次数?其实本质上如果你需要第二次结果集的时候还是需要去给Oracle一个指令,告诉他我用的是哪次结果集。但这对Oracle来说是没必要的,因为Oracle为了处理大数据(100W条记录以上)内部是已经有缓存机制的,这个目的就是会有优化性能,这一点mysql是没有的。如果像你实际的那种情况,多Oracle来说,你执行一个特殊的指令告诉它需要哪次结果集,告诉它需要几次还不如你把sql重新执行一遍,所以我觉得Oracle不可能有像你想的那种设计。如果你是从性能考虑,最好是缓存,如果操作只涉及数据库,结果集更新频繁,其实都没有必要建新表去冗余,如果只是因为sql语句冗余,能选择封装吗?或者我实在写不出别的方法了。
@Ben_Mario: 首先谢谢你的回复,感觉你分析的很到位,而且全都切中要点,好多地方也是我没有想到的,另外我觉得这种设计应该是可以有的,类似于with as用法,我们把查询的结果集存在一个临时变量里,但是我们使用一次后,这个临时变量就不能使用了,我们应该可以猜测它大概的实现原理,应该是临时变量一旦使用后就回收了这个临时变量。不知道oracle有没有能让我们手动来处理这个临时变量的设置。如果没有提供这种设置,我估计类似于jvm,害怕我们忘记自动回收更引起其他的性能问题,然后就是请教一下,我们查询过的结果集,我们怎么再次找到他(类似于通过句柄查询)。就是类似于我们直接从缓冲区找结果集,而不是直接再执行一次SQL,再次感谢!
@Yesdito: 我明白你说的创建变量的意思,打个比方: select * from t_table t,这个过程t其实就是对t_table存储的临时变量吧,这个问题我想到两点,没有深入研究过:1.这个变量之存储了t_table的结构;2.t对整个t_table进行了临时存储。如果是第一种:目的应该是为了方便简化sql;如果是第二种:不仅可以方便优化sql,还可以优化性能,我的理解是创建了临时表,临时表是有生命周期的,最长的生命周期是保证一次会话有效。我觉得你需要的是不止一次会话有效。你需要的效果应该是第二次 get(或者是其他指令) t 就能的到t_table的数据,我觉得这种设计是没有意义的,如果你是设计师:1.在使用习惯上需要保证是大部分人可以接受的;2.性能上的优化;如果是你想的哪种设计,在使用习惯上就出现了问题,正常我们要得到数据到时执行sql:select 需要的字段 form 那张表 条件等,你那种是直接选择一张表。
还是给你上面的建议:如果结果集变动频繁,那就不要想解决方案了,该执行多少次sql就执行多少sql吧。我写过30多行的sql,17张表的关联关系。这种问题本质是数据库表设计的问题,因为随着业务的扩展加表是很正常的事情,没办法一次性设计好。
@Ben_Mario: 听了你的解答,对这块的理解加深了许多,也促使我对其更深入的研究,谢谢你的回复,希望有机会继续向你请教!
数据库临时表
or
plsql的内存对象类型:嵌套表 或 索引表
首先谢谢你的回复,创建表确实可以解决这个问题,但想的有没有更小的代价来实现。
临时表的方案貌似是有可能的,但临时表最大只在一次会话中有用,其实就是oracle做了缓存表,但还是需要执行第二次查询到的能起到减少sql的作用,但新建的会话连接是不能访问的,所以不清数具体是怎么使用的会话连接,plsql只是一个数据库连接工具,个人觉得一般流程上不会用到这种工具,都是在开发的时候或者是维护数据的时候会用到