提高数据库写性能总结。
对于单条数据写操作
对于写单条数据INSERT table(`a`,`b`......) VALUES(......);的效率比INSERT table VALUES(......)要低,尽量采用后者。对于自动增加的id,可以采用INSERT table VALUES(default,......)。
尽可能一次写多条数据
一次写多条数据(批处理)比写n次单条数据的性能要显著高:
- 采用INSERT table VALUES(...),(...),(...),(...),(...)的方式
- 需要注意对于AUTO_INCREMENT的ID,采用default,不要使用ARCHIVE引擎,在写频繁的时候,容易出现Id冲突
- 尽可能选择MyISAM,显著比InnoDB性能高。
- 在试验中,Memory的效率并未显著比MyISAM高,所以还是选择MyISAM
- 如果需要带有条件,采用Batch的方式,例如"INSERT table VALUES(?,?,?,?,?) ON DUPLICATE KEY UPDATE `a`=`a`+?,`b`=`b`+?
String sql = "INSERT table VALUES(?,?,?,?) ON DUPLICATE KEY UPDATE `a`=`a`+?,`b`=`b`+?,`c`=`c`+?";
......
try ( PreparedStatement ps = dbConnection.prepareStatement(sql)){
for(MyData data : dataes){
ps.setString(1, data.getName());
ps.setLong(2, data.getA());
ps.setLong(3, data.getB());
ps.setLong(4, data.getC());
ps.setLong(5, data.getA());
ps.setLong(6, data.getB());
ps.setLong(7, data.getC());
ps.addBatch();
}
ps.executeBatch();
} catch(Exception e){
......
}
对于写压力大的项目
- 尽可能一次写多条数据
- 尽可能每次写的条目数基本相同
- 尽可能使用线程池(ExecutorService)代替线程
- 性能突然下降,可能因此到达I/O瓶颈,需要采用分库或者固态硬盘,但也可能是网络瓶颈。