需求:每小时同步一次数据,一天最多答十几万条。
由于刚进公司不久,小白只会PHP,所以第一时间会考虑用PHP实现,每次都是先truncate table 在插入表。
PHP初次实现
- 获取所有的表名
- 根据表名获取数据
- 一条一条插入数据(一条一条)
下面是获取所有的数据后进行插入
//插入一个数据库的数据道 gamedata数据库
foreach ($datain as $k => $data) {
$this->db = $this->load->database('default', TRUE);
$table = 'report_record';
if (!empty($data)) {
$this->db->insert($table, $data);
}
}
第二次 PHP优化
每天上班第一件事,看进程有没有挂,果然挂了,经测试原来是内存不足所导致的。因此不能一次性插入所有的数据,想到自己每次同步的时间有点长,所以插入数据分为四次插入(注意分四次 因为有四个库),同事吧内存设置大点,这样性能已改要好点。
$return_data = [];
foreach ($table1 as $table) {
$sql = "select substring(create_time,1,10) dt, channelid,appid,baiduid from {$table}
where substring(create_time,1,10)=DATE_SUB(curdate(),INTERVAL 0 DAY) ";
//echo $sql;
$data = $this->db1->query($sql)->result_array();
if (!empty($data)) {
$return_data[] = $data;
}
}
$insert_sql = '';
$num = 0;
$time = date("Y-m-d H:i:s");
if (!empty($return_data)) {
foreach ($return_data as $item1) {
foreach ($item1 as $item2) {
if (!empty($item2)) {
$num++;
$insert_sql .= "('{$item2['appid']}','{$time}','{$item2['dt']}','{$item2['channelid']}','{$item2['baiduid']}'),";
}
}
}
$insert_sql = rtrim($insert_sql, ',');
$this->db_sync->query($insert_sql_start . $insert_sql);
error_log(date("Y-m-d H:i:s") . print_r('insert sql1 ' . $num . "\n", TRUE), 3, '/tmp/userchannellog');
}
第三次优化 使用shell
由于每次同步是一个表一个表的插入(时间大概需要3分钟),当我在同步时,别人使用我的表,导致显示的数据会存在上一个小时的数据不当前时间的数据少。更同事讨论了一会。有两种方案:
- 用PHP实现,建一个临时表,每次同步的数据插入到一个临时表中,最后再把临时表同步到自己的表中,这样误差会很小,对于十几万左右数据。
- 用shell脚本,因此在这里就不用担心内存问题。把所有数据同步到一个文件里,最终直接导入。这样误差也会很小,对于十几万左右数。
到这里我对以上者两种方法运行效率有了兴趣。当然我最终选择用shell脚本实现。
10万条数据对比:
120万条数据运行对比如下:
今天终于写完自己的博客了。在这实习期间总是觉得时间不够用。