1.行数为亿作单位
当oracle表中行数上百万,上千万,上亿的时候,插入和查询的速度就特别慢。所以需要对读写都优化。
2.插入优化
插入使用批量插入
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.sqlException;
public class DBHelper {
public static final String url = "jdbc:oracle:thin:@//IP:1523/数据库名";
public static final String name = "oracle.jdbc.driver.OracleDriver";
public static final String user = "";
public static final String password = "";
public Connection conn = null;
public PreparedStatement pst = null; // 预处理,比Statement好
// 构造函数是用来连接数据库的
public DBHelper() throws Exception {
Class.forName(name);// 指定连接类型
conn = DriverManager.getConnection(url,user,password);// 获取连接
if (!conn.isClosed())
System.out.println("Succeeded connecting to the Database!");
}
public PreparedStatement excutesql(String sql) throws sqlException {
pst = conn.prepareStatement(sql);// 准备执行语句
return pst;
}
public void close() {
try {
this.conn.close();
this.pst.close();
} catch (sqlException e) {
e.printStackTrace();
}
}
}
val number_to_submit =100000
val sql="insert into 表名 (字段1,字段2) values (?,?)"
val dbHelper = new DBHelper()
//采用批量插入
dbHelper.conn.setAutoCommit(false)
dbHelper.pst = dbHelper.conn.prepareStatement(sql)
var count = 0 //计数
for(int i=0;i<100000000;i++){
dbHelper.pst.setString(1,"xxx")
dbHelper.pst.setString(2,"xxx")
dbHelper.pst.addBatch()
count = count + 1
//每number_to_submit次提交一下
if (count % number_to_submit == 0) {
dbHelper.pst.executeBatch() // 执行批量处理
dbHelper.conn.commit() // 提交
count = 0
}
}
//此时满足条目数小于number_to_submit以及每number_to_submit条提交之后剩下的零头的提交
if (count != 0) {
dbHelper.pst.executeBatch() // 执行批量处理
dbHelper.conn.commit() // 提交
}
dbHelper.close()
3.查询优化
建立主键和索引,加快查询速度。
在需要where的字段上建索引
INDEX_1 是自己取的索引名字
create index INDEX_1 on 表名 (字段1,字段2)
pk_1 是自己取的主键的名字
alter table 表名 add constraint pk_1 primary key (字段)
但是呢,主键默认会变成索引,再加上自己建的索引,每次插入都会判断索引,索引还会重建,所以啊,插入速度就很慢了。那么:
可以采用在插入前,删除主键以及索引,等插完了,再给建回去。
drop index INDEX_1
alter table 表名 drop constraint pk_1
不过,此方法只适用于插入在夜晚使用,凌晨时分,开始插,早上插完,白天前台页面就可以使用了。
但是如果数据需要不停的大批量插入,每时每刻都有大量数据要插,前台还要经常查询,不可以用此方法。
应该是也不会有这样的需求。
4.将表缓存到内存中
这种情况是热点表需要经常查询,且表的占用容量不大,一般如果几个G就不建议这样做了,可以做分区,做索引。
如果表不是很大,比如几百M,然后需要快速响应的,可以将表放入内存中。
例:将fisher表缓存到内存中
1)alter table fisher cache;
2)alter table fisher storage(buffer_pool keep);
--取消缓存
1)alter table fisher nocache;
2)alter table fisher storage(buffer_pool default);
select table_name,OWNER,cache,buffer_pool from dba_tables where table_name='FISHER'; --查看是否缓存
select * from dba_segments where segment_name='FISHER' ; --查看表大小
两者区别:
1) cache是将表缓存到share pool 中,该操作直接将表缓存的热端,受LRU算法控制。
2)将表缓存到一个固定的内存空间中,默认情况下buffer_pool空间为0,。需手动设置空间大小:
alter system set db_keep_cache_size = 10M