具体场景描述:
比如,某网站有100万个会员,每个会员每个月都会在网站进行消费,每个月有且仅有一次消费,有专门的表存放这些消费记录。也就是说,在这个消费记录表里,每个月都会新增100万条记录。
那么网站现在有一个需求:对这些会员的消费进行跟踪调查。具体描述:网站每年不定期根据行情设置一个消费金额上限和下限,网站统计每位会员当时的消费是否在当时的上限和下限之间,并将该统计结果存放在一张表中。(例如:网站在2007年1月10日,设置了一个上限和下限,在2008年3月5日,设置了一个新的上限和下限,那么网站会员在2008年3月4日的消费金额,统计结果参考2007年3月5日设置的上限和下限,而在2008年3月5日的消费金额,统计结果应该参考2008年3月5日新设置的上限和下限。)当然,我这里只是模拟一个环境,并不是在做传销。呵呵。
我的思路是做增量存储,写一存储过程实现上面描述的需求,存储过程每天执行一次,只对每天新增的消费信息进行统计,不用每天都把N年的数据全部重新统计一次。没个月100万条的数据平均每天就3.3万条,这样数据库就轻松多了。再一个,我对会员信息表和消费信息表都创建了索引,这样在多表查询的时候也会提升速度。
这样做只保证了统计走入正轨以后能统计得快一点,不能保证在第一次统计的时候就有很好的效率,因为第一次统计可能要统计1年的数据,那会员信息是100万条,而消费记录可能是1200万条,那一次统计的时候,还得判断该消费记录是按照哪个消费上限和下限统计,这个速度就是鬼速了。
实际说明,我在统计的时候,存储过程都执行了3个小时了,统计表里才出现1万条记录,还是在服务器上跑。数据库是 oracle 10g。
各位高手,能有好的解决方案么,解决存储过程在第一次执行的时候的效率太低的问题,如果能提高以后每次存储过程的执行效率也请指教。 唉,一个搞技术的,写这么多文字,我都觉得不爽,没办法,见谅。
比如,某网站有100万个会员,每个会员每个月都会在网站进行消费,每个月有且仅有一次消费,有专门的表存放这些消费记录。也就是说,在这个消费记录表里,每个月都会新增100万条记录。
那么网站现在有一个需求:对这些会员的消费进行跟踪调查。具体描述:网站每年不定期根据行情设置一个消费金额上限和下限,网站统计每位会员当时的消费是否在当时的上限和下限之间,并将该统计结果存放在一张表中。(例如:网站在2007年1月10日,设置了一个上限和下限,在2008年3月5日,设置了一个新的上限和下限,那么网站会员在2008年3月4日的消费金额,统计结果参考2007年3月5日设置的上限和下限,而在2008年3月5日的消费金额,统计结果应该参考2008年3月5日新设置的上限和下限。)当然,我这里只是模拟一个环境,并不是在做传销。呵呵。
我的思路是做增量存储,写一存储过程实现上面描述的需求,存储过程每天执行一次,只对每天新增的消费信息进行统计,不用每天都把N年的数据全部重新统计一次。没个月100万条的数据平均每天就3.3万条,这样数据库就轻松多了。再一个,我对会员信息表和消费信息表都创建了索引,这样在多表查询的时候也会提升速度。
这样做只保证了统计走入正轨以后能统计得快一点,不能保证在第一次统计的时候就有很好的效率,因为第一次统计可能要统计1年的数据,那会员信息是100万条,而消费记录可能是1200万条,那一次统计的时候,还得判断该消费记录是按照哪个消费上限和下限统计,这个速度就是鬼速了。
实际说明,我在统计的时候,存储过程都执行了3个小时了,统计表里才出现1万条记录,还是在服务器上跑。数据库是 oracle 10g。
各位高手,能有好的解决方案么,解决存储过程在第一次执行的时候的效率太低的问题,如果能提高以后每次存储过程的执行效率也请指教。 唉,一个搞技术的,写这么多文字,我都觉得不爽,没办法,见谅。
解决方案 »
- 将B表结果插入A表,如果A存在则将A中的一个字段值加1,不存在则插入新纪录
- pl/sql读写文件的错误: ORA-06510和ORA-06512
- 请大家帮忙比较下
- 请问“decode(dl_qual_2,0,0,dl_qual_1/dl_qual_2)”这一句总报错:not a group by expre
- orcal 网关透明不能连接sql server
- 求教一个正则表达式
- java.sql.SQLException: 无法从套接字读取更多的数据
- 新手求助
- 向数据库中导入imp一个表oracle 10g 实现的错误 麻烦帮忙看下 在线等!
- 请问,Oracle9i和10g有什么不同.
- 新来乍到;给各位大哥问个好;烦劳大哥们接个分……
- 业务单号生成设计方案
总的说来,你的建议确实可行,不过我有几个疑问:
1. 如何用 rowid 访问?
网站会员信息里有一个会员编号,这个是唯一的,这个字段也存放于消费信息表里,因为后期需求的需要,我还得把会员的身份证号也放到我的统计表里,也就是我用 rowid 访问消费记录表后,还得根据消费记录表的会员编号查询他的身份证号。这个身份证号是在开发后期加进去的,现在很苦恼,系统之所以慢,估计这里有一方面的原因。这是一方面,另一方面,我确实没使用过用 rowid 访问的方法,能指点指点么?2. 如何若干条提交一次?
我现在就是一条一条的提交,你的建议不错,有没有具体思路?谢谢你的回答。
比如说5000条一次commit消耗的时间,实际上和一条一次commit差不多的
但5000次一条一次是>5000条一次的
许多开发人员在事务方面都有一些不好的习惯。如果开发人员使用过另外某个数据库,其中只是“支持”事务,而没有“提升”事务的使用,执行开发人员就常常有这样的一些坏习惯。例如,在Informix(默认设置)、Sybase和SQL Server中,必须显式地BEGIN(开始)一个事务;否则,每条单个的语句本身就是一个事务。Oracle在具体的语句外包了一个SAVEPOINT,采用类似的方式,那些数据库则在各条语句外包了一个BEGIN WORK/COMMIT或ROLLBACK。这是因为,在这些数据库中,锁是稀有资源,另外读取器会阻塞写入器,反之,写入器也会阻塞读取器。为了提高并发性,这些数据库希望你的事务越小越好,有时甚至会以数据完整性为代价来做到这一点。
Oracle则采用了完全不同的方法。事务总是隐式的,没有办法“自动提交”事务,除非应用专门实现(更多详细内容请见8.4.2节)。在Oracle中, 每个事务都应该只在必要时才提交,而在此之前不能提交。事务的大小要根据需要而定。锁、阻塞等问题并不是决定事务大小的关键,数据完整性才是确定事务大小 的根本。锁不是稀有资源,并发的数据读取器和数据写入器之间不存在竞争问题。这样在数据库中就能有健壮的事务。这些事务不必很短,而要根据需求有足够长的 持续时间(但是不能不必要地太长)。事务不是为了方便计算机及其软件,而是为了保护你的数据。
8.4.1在循环中提交
如果交给你一个任务,要求更新多行,大多数程序员都会力图找出一种过程性方法,通过循环来完成这个任务,这样就能提交多行。据我听到的,这样做的两个主要原因是:
频繁地提交大量小事务比处理和提交一个大事务更快,也更高效。
没有足够的undo空间。
这 两个结论都存在误导性。另外,如果提交得太过频繁,很容易让你陷入危险,倘若更新做到一半的时候失败了,这会使你的数据库处于一种“未知”的状态。要编写 一个过程从而在出现失败的情况下能平滑地重启动,这需要复杂的逻辑。到目前为止,最好的方法是按业务过程的要求以适当的频度提交,并且相应地设置undo段大小。
提示明确表明对指定表根据ROWID进行访问.
例如:
SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA'