--插入1000万条数据 SQL> create table test_A(id number(20) primary key,name varchar2(40));Table createdSQL> select * from test_a; ID NAME --------------------- ---------------------------------------- create or replace procedure pro_test as begin for i in 1 .. 10000000 loop insert into test_a values (i,'name'||'''||i||'''); end loop; commit; end;Done in 0.141 secondes SQL> exec pro_test;PL/SQL procedure successfully completedSQL> set timing on SQL> select count(*) from test_a; COUNT(*) ---------- 10000000Executed in 5.625 secondsSQL> select count(*) from test_a; COUNT(*) ---------- 10000000Executed in 3.703 secondsSQL> select count(*) from test_a; COUNT(*) ---------- 10000000Executed in 2.484 seconds SQL> select * from test_a where id=100; ID NAME --------------------- ---------------------------------------- 100 name'||i||'Executed in 0.078 seconds
这个我也算是路过,本来不想灌水的,不过看到了,就简单说下吧;就像上面说的,这个具体情况具体分析,你说的假设中还存在很多不定性因素存在,而在一般情况下只能确定在这个字段有索引,你要找其中很少一部分数据,这部分数据一般在一个block中的话,会保持在几十毫秒以内,但是这个并非绝对值,而且这个也仅仅针对一些版本的oracle以及一定的配置环境和访问量下。首先需要看的是这个ID的宽度以及是数字还是字符串,两者的索引长度是完全不一样的,一般来说几百万的数据,一般的索引层数保持在3~4层,而如果是主键索引,这部分是属于索引组织表,它的宽度是由数据的宽度影响的(在某些情况下主键索引未必是最快速的,尤其是在INDEX FAST FULL SCAN的时候,因为它的层数可能比其他索引要大)。其次要看访问量,和cache是否命中,如果你的数据cache命中的话,可能在10ms左右就能返回,另外其他的访问可能会导致一定的排斥,尤其是再高并发的情况。还有就是在磁盘IO处索引磁盘和数据磁盘时候划分规范降低他们之间的征用,这里在并发访问的时候,还需要考虑存储设备的性能如:磁盘IOPS以及存储设备的控制器架构、存储设备的读写cache架构、存储设备的RAID方法或者ASM管理机制,如果在大数据量访问的时候还需要考虑带宽的情况。最后如果IO未命中的情况下,设置存储的IO大小有关系,举个简单例子,如果一个block为32K用在了OLTP环境,而IO大小设置为2K,此时你在读取任何一条为在内存中命中的数据将会发生16次IO(而ORACLE读取数据不会半个块或者四分之一个块的读取,都是一块读取到内存,然后做LRU队列),这也是为什么OLTP应用的BLOCK一般都比较小,而OLAP比较大的一个重要原因;顺便说下:一般一块用于随机读写的本地硬盘在小IO测试下(顺序读写的磁盘适用于日志编写的高可用性缓存数据库),单个磁盘的IOPS一般极限是150个IOPS,其中还会划分出来读IOPS和写IOPS等等,所以一次读就干掉了16个(当然我举例有点极端,呵呵,只是想说明他的影响因素的确很多)。还会有其他的影响情况,如锁机制的一致读需要到UNDO中获取等等都是需要时间开销的,这里仅仅就事论事,具体需要自己动手实践才可以得到在最适合的环境得到最佳的性能和稳定性,当然前提是要保证数据的准确性。呵呵!
我这里有个现成的 --测试表t_pc_vehicle 数据量2500W--车牌号 带索引 (可重复,具体看重复数多少了,我这个查出是一条的),查询时间0.17秒 select * from t_pc_vehicle v where v.vehicle_no = 'TD沪A-3333' --media_name 没有索引 ,查询时间108秒 select * from t_pc_vehicle v where v.media_name = 'abc'
情景我已经说出来了,我就是想看看这个速度有多快啊
--插入1000万条数据
SQL> create table test_A(id number(20) primary key,name varchar2(40));Table createdSQL> select * from test_a; ID NAME
--------------------- ----------------------------------------
create or replace procedure pro_test as
begin
for i in 1 .. 10000000 loop
insert into test_a values (i,'name'||'''||i||''');
end loop;
commit;
end;Done in 0.141 secondes
SQL> exec pro_test;PL/SQL procedure successfully completedSQL> set timing on
SQL> select count(*) from test_a; COUNT(*)
----------
10000000Executed in 5.625 secondsSQL> select count(*) from test_a; COUNT(*)
----------
10000000Executed in 3.703 secondsSQL> select count(*) from test_a; COUNT(*)
----------
10000000Executed in 2.484 seconds
SQL> select * from test_a where id=100; ID NAME
--------------------- ----------------------------------------
100 name'||i||'Executed in 0.078 seconds
如果按照其他非主键字段分区,那么oracle将会按照这个id=‘55555555’进行多个分区的查询,
--测试表t_pc_vehicle 数据量2500W--车牌号 带索引 (可重复,具体看重复数多少了,我这个查出是一条的),查询时间0.17秒
select * from t_pc_vehicle v where v.vehicle_no = 'TD沪A-3333' --media_name 没有索引 ,查询时间108秒
select * from t_pc_vehicle v where v.media_name = 'abc'
没有具体的定论
不过一些最基本的规则不管是Oravle还是SQL都要遵守的