用select * from table_name;从一张大表(几千w条数据)里面取数
并保存存文件发现在不同时间段取数速度大不相同在12点时开始启动程序load数据,要一直等到3点多时还没取完(最后因为回滚段不足程序出错)
而在这段时间内的2点左右,启动同样的程序,却在1小时内load完即先启动的程序比慢启动程序还更完跑完程序和sql是一样的,连接的数据库也是一样的。
=======================
有什么可能原因会造成这样的结果 有没有什么方法避免这种事情?
并保存存文件发现在不同时间段取数速度大不相同在12点时开始启动程序load数据,要一直等到3点多时还没取完(最后因为回滚段不足程序出错)
而在这段时间内的2点左右,启动同样的程序,却在1小时内load完即先启动的程序比慢启动程序还更完跑完程序和sql是一样的,连接的数据库也是一样的。
=======================
有什么可能原因会造成这样的结果 有没有什么方法避免这种事情?
可能跟业务有关,就是指在12:00到2:00这段时间里面,数据库有大量的业务操作,所以影响了你的proc的取数据事务。
在大批量insert、update或者delete业务的情况,会锁表的记录,这样会导致程序读取数据库表的时候缓慢,避免的办法是,不要在大批量业务操作的情况下,执行你的程序。
如果修改操作对表有影响,那理论之后启的程序自然也是受到同样影响
毕竟是同一个环境另外,还有一点不明白的是,为什么写操作会影响读操作速度
之间好像看过文章介绍oracle对这种同时读写操作支持性很好
读程序所在的机器IO和CPU都是十分空闲的
数据库所在的机器这些参数要怎么获得?有什么sql可以查询吗?
这个说的很好。我觉得问题可能有:1)楼主的UNDO太小了,或者UNDO_RETENTION设置的太短2)楼主的代码,用了游标来循环取数据
你也可以安装一个osw,这样就可以实时的记录你的machine情况
读一致性是这样实现的:
1:任何DML操作都会产生一个事务SCN号,保存在数据块ITL槽中,它的值与事务完成那一刻的时间对应。
2:事务操作会在数据块中记录相应的UNDO块的地址。
如果你在12点发出一个查询,服务器就会产生一个12:00这个时刻的SCN号,然后将数据块中ITL槽的SCN号与这个进行对比,如果12:00以后该数据没有被修改,那么该数据块的ITL槽SCN号肯定比12:00要小,如果12:00以后修改过,那么就比12:00大,一旦判定大于12:00,oracle会根据undo块的地址寻找到undo块,重新构造修改前的数据。如果这个块做过两次DML操作,甚至还要根据undo块再构造一次数据。直到scn号比12:00小。
要根据地址构造数据,还要取数,这个过程当然没有直接得到数据快。