ThinkPHP操作MySQL删除大量数据的优化
2016-10-18 22:19
211 查看
我对有一个8万条数据的表进行了一次去重操作,其中有将近6万条的重复数据需要被删除。考虑到可能会产生对数据库的高IO操作,我选择进行删除算法的优化。
读取过之后进行了三次正则匹配
第一次正则匹配,匹配出长度为十位的学号,保存到数组里面。
第二次正则匹配,匹配出所有包含汉字的第一个符合项。
第三次正则匹配,匹配出长度为十八位的身份证号。在匹配身份证号的时候要注意最后一位可能是x,所以正则表达式我写的是前十七位为数字,后一位自行判断是数字还是字母。
所有的数据都被读取出来之后,我进行了一个非空判断,对当行的数据进行插入操作,然后,继续读取下一行,当所有的行都没读取完之后要进行文件的关闭操作。
与此同时,我在函数的开始和函数的结束,加上了时间判断符,最后打印出时间的消耗,大概每次执行函数的时间在66秒左右。
通过idcode字段将相同的身份证号按组排列起来,并且选出组中最小的那个id,相当于不重复的唯一的一条数据,然后用foreach循环。
将字符串组合成逗号连接的数组。按每1000条为一个组进行删除。这样做的好处是防止在同时删除上万条数据的时候,数据库崩溃或者是操作超时。
第一个函数
获取要删除的id数组
从原来的sql数据文档里面读取出来这8万条数据并保存到数组中。为了防止数据溢出,我选择逐行读取,数据的大小分4k储存.读取过之后进行了三次正则匹配
第一次正则匹配,匹配出长度为十位的学号,保存到数组里面。
第二次正则匹配,匹配出所有包含汉字的第一个符合项。
第三次正则匹配,匹配出长度为十八位的身份证号。在匹配身份证号的时候要注意最后一位可能是x,所以正则表达式我写的是前十七位为数字,后一位自行判断是数字还是字母。
所有的数据都被读取出来之后,我进行了一个非空判断,对当行的数据进行插入操作,然后,继续读取下一行,当所有的行都没读取完之后要进行文件的关闭操作。
与此同时,我在函数的开始和函数的结束,加上了时间判断符,最后打印出时间的消耗,大概每次执行函数的时间在66秒左右。
第二个函数
分批次删除数据
将重复的id保存下来。通过idcode字段将相同的身份证号按组排列起来,并且选出组中最小的那个id,相当于不重复的唯一的一条数据,然后用foreach循环。
将字符串组合成逗号连接的数组。按每1000条为一个组进行删除。这样做的好处是防止在同时删除上万条数据的时候,数据库崩溃或者是操作超时。
public function getArray() { set_time_limit(120); $DB = M('code'); $handle = @fopen("C:/Users/Administrator/Desktop/xcu/UserData/user.sql", "r"); $t1 = microtime(true); if ($handle) { while (!feof($handle)) { $buffer = fgets($handle, 4096); if (preg_match('/[\d]{10}\b/', $buffer, $match)) { $array['sid'] = $match[0]; if (preg_match('/[\x7f-\xff]+/', $buffer, $match)) { $array['name'] = iconv('gbk', 'utf-8', $match[0]); if (preg_match('/\d{17}[\d|X|x]/', $buffer, $match)) { $array['idcode'] = $match[0]; } } } if (!empty($array)) { $DB->data($array)->add(); } } fclose($handle); } $t2 = microtime(true); echo '耗时' . round($t2 - $t1, 3) . '秒'; } public function delData() { set_time_limit(120); $DB = M('code'); $res = $DB->field('min(id) as id')->group('idcode')->select(); $t1 = microtime(true); $arr = ""; $count = 0; foreach ($res as $val) { $count++; //var_dump($val['id'].'<br>'); $arr.= ",".$val['id']; if ($count % 1000 == 0){ echo substr($arr,1).'<br>'; $map["id"] = array('in', substr($arr,1)); $sqlres = $DB->where($map)->delete(); if ($sqlres){ echo "批次删除成功!"; } $arr = ""; } } $t2 = microtime(true); echo '耗时' . round($t2 - $t1, 3) . '秒'; }
相关文章推荐
- 记一次mysql删除大量数据的优化
- MSSQL、MySQL 数据库删除大批量千万级百万级数据的优化
- 【SQL Server性能优化】删除大量数据的方法比较
- mysql操作技巧随笔--链表删除数据
- Thinkphp数据的修改及删除操作
- Mysql大量插入数据时SQL语句的优化
- Asp.Net 2.0 操作mysql 数据基类(读取,删除,插入,更新)
- php导入大量数据到mysql性能优化技巧
- MySQL数据记录基本操作——添加数据、更新数据和删除数据
- vb操作mysql之数据删除与增加
- Thinkphp 数据的修改及删除操作
- python对MySQL进行数据的插入、更新和删除之后需要commit,数据库才会真的有数据操作。(待日后更新)
- php导入大量数据到mysql性能优化技巧
- Mysql载入大量数据(load data infile)的优化过程
- Asp.Net 2.0 操作mysql 数据基类(读取,删除,插入,更新)
- 【SQL Server性能优化】大量数据删除的方法比较
- mysql的大量数据操作技巧
- C++操作MySQL大量数据插入效率低下的解决方法
- mysql单表数据操作优化(一)
- MySQL数据表创建删除操作