怎样将MySQL中两千万数据进行优化与迁移
技术百科
怪我咯
发布时间:2017-04-05
浏览: 次 最近有一张2000W条记录的数据表需要优化和迁移。2000W数据对于http://www./wiki/1160.html" target="_blank">MySQL来说很尴尬,因为合理的创建索引速度还是挺快的,再怎么优化速度也得不到多大提升。不过这些数据有大量的冗余字段和错误信息,极不方便做统计和分析。所以我需要创建一张新表,把旧表中的数据一条一条取出来优化后放回新表;
一. 清除冗余数据,优化字段结构
2000W数据中,能作为查询条件的字段我们是预知的。所以将这部分数据单独创建新的字段,对于有规则的数据合理改变字段结构,
比如身份证就是varchar(18)。对于不重要的数据我们合并后存在一个结构为text的字段。
对于一些有关联的数据我们需要计算,常见的比如身份证种能获取到准确的性别,出生地、生日、年龄。
二. 数据迁移
我们从数据库中取出一条旧数据,再通过计算处理后得到想要的新数据,最后将新数据插入新表。不过在获取新数据时遇到如下问题。
-
数据量太大,无法一次获取(2000w数据扔到内存挺可怕的);
我们可以通过MySQL的limit语法分批获取。比如每次获取50000,SQL语句如下:
select * from table_name limit 15000000,50000;
通过这种方法能解决数据量太大的问题,但是随着limit的第一个参数越来越大,查询速度会慢的吓人(上面这条SQL执行会花35秒)。时间就是生命,于是我们开始优化SQL语句,优化后变成下面这样:
select * from table_name order by id desc limit 5000000,50000;
可通过二分法拆分2000W数据,当执行到1000W数据时,将数据倒序。优化后SQL执行效率显著提升,从35秒降到9秒;
不过还是很慢,时间就是生命……还好我们有自增ID(创建数据表第一条定律,一定要有自增字段),优化后的SQl如下:
1. select * from table_name where id>15000000 and id<15050000; 2. select * from table_name where id>15000000 limit 50000;
为了直观演示,我写了两条功能一样的SQL。相比第一条,第二条的limit会导致SQL的索引命中变差,效率同样也会下降。第一条SQL的执行时间是2毫秒,第二条执行时间5毫秒(我取的平均值)。每次数据的查询速度直接从35秒降到2毫秒……
-
数据量太大并且数据无法预估,某些特殊数据会导致数据导入失败;
我们有三种方案去将新数据存入新表,分别如下:
-
一条一条插入数据;
开始肯定会想这种方案一定不行,因为每次插入都会有一次数据库IO操作。但是该方案有个好处是能及时发现有问题的数据,修改后再继续执行; 在Oracle中使用『绑定变量』能带来性能提升,正好MySQL也提供了『绑定变量』的功能。于是在不改变逻辑的情况下,尝试优化数据存储速度。代码如下:
public function actionTest(array $data) { $mysqli = new mysqli("192.168.1.106", "username", "password", "test"); $sql = "insert into table_name(name,identity) values (?,?)"; $stmt = $connection->prepare($sql); $name = ""; $identity = ""; //使用绑定变量 $stmt->bind_param("si", $name, $identity); foreach($data as $val) { $name = $val[name]; $identity = $val[card_id]; //执行 $stmt->execute(); } $stmt->close(); }最后效果不怎么好,MySQL的『绑定变量』并没带来明显的速度提升,不过能有效的防止SQL注入;
-
一次插入50000条数据;
这是我最后选中的方案,一是能及时发现有问题的数据,二是导入数据非常稳定。就像支持断点续传一样,每一步都能看到效果。在执行脚本时,也能同步开始写分析逻辑;
-
组装成SQL文件,最后统一导入;
组装一个大的SQL文件,最后通过MySQL自带的工具导入也是极好的。但如果有一条SQL有问题,你可能需要重跑一次脚本。因为在9G大小的文本文件中修改一个符号是很痛苦的事情……
三. 总结
通过各种优化,最后将脚本执行时间缩短到了20分钟内。优化后数据质量得到了较高保证,下次将尝试2亿数据的优化&迁移……
# 是在
# 就像
# 也会
# 绑定
# 太大
# mysql
# 后将
# 执行时间
# 第一条
# 第二条
# 发现有
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- C++如何获取CPU核心数?(std::threa
- Windows服务无法启动错误1067是什么_进程
- Win11开机Logo怎么换_Win11自定义启动
- Dapper的Execute方法的返回值是什么意思
- Win11如何设置鼠标灵敏度_Win11鼠标灵敏度
- XAMPP 启动失败(Apache 突然停止)的终
- Win10任务栏天气和资讯怎么关闭 Win10禁用
- c# await 一个已经完成的Task会发生什么
- php订单日志怎么记录评价_php记录订单评价日志
- Win11怎么关闭通知中心_Windows11系统
- 如何在 Go 中正确初始化结构体中的 map 字段
- Windows10电脑怎么设置文件权限_Win10
- PythonGIL机制理解_多线程限制解析【教程】
- Windows驱动无法加载错误解决方法_驱动签名验
- Windows如何拦截腾讯视频广告_Windows
- Python对象比较排序规则_集合使用说明【指导】
- Win11鼠标灵敏度怎么调 Win11鼠标指针移动
- Win11怎么把图标拖到任务栏_Win11固定应用
- Mac如何与安卓手机传文件_Mac和Android
- Win11怎么关闭用户账户控制UAC_Window
- Win11怎么更改任务栏颜色_Windows11个
- Linux如何安装Golang环境_Linux下G
- c++获取当前时间戳_c++ time函数使用详解
- Django 测试数据库表缺失与字段未创建问题的完
- LINUX如何查看文件类型_Linux中file命
- PHP主流架构怎么处理表单验证_规则与自定义【技巧
- PHP主流架构怎么集成Redis缓存_配置步骤【方
- Win11怎么设置系统还原_Windows11系统
- 如何使用Golang log记录不同级别日志_Go
- Windows 10怎么隐藏特定更新补丁_Wind
- c++ unordered_map怎么用 c++哈
- c++怎么使用std::filesystem遍历文
- Windows10系统怎么查看硬盘健康_Win10
- 如何在Windows上设置闹钟和计时器_系统自带的
- LINUX怎么进行文本内容搜索_Linux gre
- 如何使用Golang进行HTTP服务性能测试_测量
- 如何使用Golang优化模块引入路径_Golang
- 如何在Golang中验证模块完整性_Golangg
- 如何使用Golang实现云原生应用弹性伸缩_自动应
- c++ atoi和atof函数用法_c++字符数组
- Python抽象类与接口设计_规范说明【指导】
- Python生成器表达式内存优化_惰性计算说明【指
- 如何在Golang中实现并发消息队列消费者_Gol
- php订单日志权限怎么设_php订单日志文件权限设
- Windows蓝屏错误0x00000023怎么修复
- Mac的“调度中心”与“空间”怎么用_Mac多桌面
- 作用域操作符会影响性能吗_php静态调用性能分析【
- LINUX的SELinux是什么_详解LINUX强
- 使用类变量定义字符串常量时的类型安全最佳实践
- Win11玩游戏全屏闪退怎么办_Win11全屏优化

QQ客服