发表于: 2017-10-05 21:10:55
1 759
今日任务:
步骤28,先对插入语句直接不加修饰赤裸裸的插入100W条数据,平均速度差不多是1秒1000条左右的样子,逛了会儿知乎才搞定。
得想办法优化,第一个通过拓宽每句的sql来达到快速插入的效果,
INSERT table_name (column1, column2, ..., columnN)
VALUES (rec1_val1, rec1_val2, ..., rec1_valN),
(rec2_val1, rec2_val2, ..., rec2_valN),
... ...
(recM_val1, recM_val2, ..., recM_valN);
在java中通过将sql语句类型从String转换成StringBuffer,然后对StringBuffer.append(",recM_val1, recM_val2, ..., recM_valN")来进行叠加,但因其一句sql语句有长度限制,我这边就叠加到了5W句,插入一次的时间大概是2秒,再在外面套一个循环20次,大约在12秒左右,
public static void main(String[] args) throws SQLException {
ComboPooledDataSource cd = new ComboPooledDataSource();
Connection connection = cd.getConnection();
for (int j=0;j<20;j++) {
StringBuffer sql = new StringBuffer("insert into student(id,name) values(0,'刘能')");
for (int i = 1; i < 50000; i++) {
sql.append(",(" + i + ",'刘能')");
}
String mysql = sql.toString();
PreparedStatement p = connection.prepareStatement(mysql);
p.executeUpdate();
p.close();
}
}
那么在这里删除所有数据,将id设为主键索引测试,再删除主键索引对姓名创建普通索引,均花费约16秒,。
public class Test {
public static void main(String[] args) throws SQLException {
Long begin = new Date().getTime();
ComboPooledDataSource cd = new ComboPooledDataSource();
Connection connection = cd.getConnection();
for (int j=1;j<=20;j++) {
StringBuffer sql = new StringBuffer("insert into student(id,name) values("+50000*(j-1)+",'刘能')");
for (int i = 50000*(j-1)+1; i < 50000*j; i++) {
sql.append(",(" + i + ",'刘能')");
}
String mysql = sql.toString();
PreparedStatement p = connection.prepareStatement(mysql);
p.executeUpdate();
p.close();
}
Long end = new Date().getTime();
System.out.println("cast : " + (end - begin) / 1000 + " s");
}
}
索引采用B+TREE结构,使得查询时速度得到了N倍的提升,但增删改数据使得数据库得花费多余的时间去维护数据结构,不能盲目添加索引!
网上查询还有一种是采用多线程优化的,但是我对线程这块没怎么学得好,只能暂时标记STOP。
按照师兄所说对domain,service,dao写组件,实行对数据库的增删改查,这里采用了spring jdbc 来操作数据库整体结构如下
@Component("taskDao")
public class TaskDaoImpl implements TaskDao {
@Resource
private JdbcTemplate jdbcTemplate;
@Override
public void task_add() {
String sql = "insert into student(id,name) values(1,'刘能')";
jdbcTemplate.update(sql);
}
@Override
public void task_delete(int id) {
String sql = "delete from student where id=?";
jdbcTemplate.update(sql,id);
}
@Override
public void task_update() {
String sql = "update student set name='赵四' where id=1";
jdbcTemplate.update(sql);
}
@Override
public List<Map<String, Object>> findAll() {
String sql = "select id,name from student";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
return list;
}
}
@Component("taskService")
public class TaskServiceImpl implements TaskService{
@Resource
private TaskDao taskDao;
@Override
public void add() { taskDao.task_add(); }
@Override
public void delete(int id) {
taskDao.task_delete(id);
}
@Override
public void update() {
taskDao.task_update();
}
@Override
public List<Map<String, Object>> findAll() {
List<Map<String, Object>> list = taskDao.findAll();
return list;
}
}
配置文件设置如下
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mydemo"></property>
<property name="user" value="root"></property>
<property name="password" value="8866521"></property>
<property name="initialPoolSize" value="5"></property>
<property name="maxPoolSize" value="10"></property>
<property name="maxIdleTime" value="1000"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<context:component-scan base-package="cn.task1.*"></context:component-scan>
这里要注意,因为分离了接口和实现,在使用实现类注入IOC容器中时,引用名特意修改成接口名,这样在使用@Resource取出时,父类接口实现子类对象,从而调用子类方法,测试通过!
返回步骤二十七,根据规范对表格进行规范创建,创建数据库
create database it_task1;
创建用户表
create table task1_user(
userCreate_at date,
userUpdate_at date,
userId int primary key,
userName varchar(10),
userQq varchar(15),
userChoiceType int,
userEntranceTime date,
userGraduationSchool varchar(20),
userDailyUrl varchar(30),
userDesire varchar(50),
usersBrother varchar(10)
);
这里在创建修真类型表
create table task1_cultivation(
cultivationId int primary key,
cultivationName varchar(15),
cultivationCreate_at date,
cultivationUpdate_at date
)
这里用户表和修真类型表为多对多关系,用户表userChoiceType添加外键约束
alter table task1_user add constraint fk_user_cultivation foreign key (userChoiceType) references task1_cultivation(cultivationId);
大功搞成!
task1正式提交,总体难度很高,做的过程中感觉自己知识漏洞还很大,基本概念底层原理很多还是懵懵懂懂的感觉。
任务小结:
整体大致分为
① 步骤1-步骤11,步骤1其实感觉很坑,对于纯新手来说对象、物理模型这些概念不是特别的清楚,建议直接跳过上手步骤2,在安装完Mysql和Navicat后开始1-2天的SQL语句的学习,之后开始对步骤1分析并创建表格练习增删改查、
②步骤12-步骤16,无基础的开始学习JAVA,得高强度下花费3-5天了解基本概念,各种各样的语句语法,并且之后每天都需花费时间多一个线程来学习JAVA,同时开始熟悉MAVEN,路径的问题困扰了我几次。
③步骤17-步骤19,这是非常非常容易卡壳的地方,学习方向从JDBC到C3P0(1天),学习Spring框架中的IOC和DI核心容器的概念,JDBC Template是依赖在Spring框架基础上已C3P0为连接基础的语法(3天),Mybatis是另外一款截然不同的持久层框架,了解映射概念(1天),这里Spring AOP概念不推荐学 先放放,概念性太强。完成后接触DAO概念,了解分层机制,稍微学习一些web方面知识
④步骤20-步骤21 学习测试及调试。
⑤步骤22-步骤24 购买服务器,学习部署过程,学习web基础相关知识,学习tomcat使用。
⑥步骤25-步骤28 强化数据库知识概念,并将前面所学融会贯通。
明日计划:先整合spring和mybatis后再开始task2,每天都有欠账,补不过来了都。。。
问题:无
收获:多写才会多错,多错才知道什么薄弱点在哪儿。可惜因为牙齿问题,报名线下得延后一星期了
评论