休闲

MySQL开发技巧批量数据入库及检索

时间:2010-12-5 17:23:32  作者:娱乐   来源:时尚  查看:  评论:0
内容摘要:批量入库,最忌讳一条条insert。MySQL 8.0 之前,单条insert的往返开销占了大头,网络延迟、SQL解析、事务提交,每一层都在拖后腿。我见过一个团队,往一张50万行的表里导数据,用循环插

批量入库,开库及最忌讳一条条insert。发技MySQL 8.0 之前,巧批单条insert的量数往返开销占了大头,网络延迟、据入检索SQL解析、开库及事务提交,发技每一层都在拖后腿。巧批我见过一个团队,量数往一张50万行的据入检索表里导数据,用循环插入跑了快两小时,开库及后来换成load data,发技25秒结束。巧批差距就这么离谱。量数 要提速,据入检索先得理解MySQL的写入瓶颈在哪。除了网络和解析,还有索引维护、binlog同步、redo log刷盘。批量插入时,这些开销会被摊薄,但摊薄的前提是你用对了工具。`INSERT INTO ... VALUES (...), (...), (...)` 这种多值语法是最基础的优化,一次拼个500到1000条,比逐条快一个数量级。但别贪,超过1万条,SQL包太大,反而容易触发max_allowed_packet限制,得不偿失。 真到百万级,别犹豫,上`LOAD DATA INFILE`。这玩意儿是MySQL原生导入工具,走的是文本解析加批量插入路径,比任何ORM的bulk_create都快。我实测过,3GB的CSV,带索引导入大概4分钟,前提是关掉唯一键检查和binlog,导入完再重建。具体操作:导入前`SET UNIQUE_CHECKS=0; SET FOREIGN_KEY_CHECKS=0;`,导完再开回来。代价是中途断电可能丢数据,但开发环境谁在乎?生产环境你按备份恢复就行。 检索那块,很多人忽略一个细节:批量插入后,索引统计信息是旧的。MySQL优化器靠统计信息选索引,旧数据会误导它。插入完立刻`ANALYZE TABLE`,让优化器重新采样,否则可能全表扫描。我调过一个慢查询,数据量才20万,但查询跑了3秒,一查统计信息还是刚建表时的,analyze之后降到50毫秒。这操作成本极低,收益极大,但90%的人想不到。 再说检索技巧。批量数据入库后,查询别上来就`SELECT *`。你只需要id和name,就别把20个字段全拖出来,内存和IO都在浪费。还有,`WHERE`条件里字段类型要匹配,索引列上做函数运算会让索引失效。比如`WHERE DATE(create_time) = '2024-01-01'`,这写法MySQL没法用索引,得改成`WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02'`。区间扫描比全表扫快十倍不止。 排序和分页也有坑。`ORDER BY` 字段要跟索引顺序一致,否则filesort。分页深了,`LIMIT 100000, 20` 这种,MySQL得先扫10万行再丢,慢得离谱。用延迟关联:先查主键,再join原表取数据。比如`SELECT * FROM t JOIN (SELECT id FROM t ORDER BY create_time LIMIT 100000, 20) tmp ON t.id = tmp.id`,这招能扛住千万级分页。 最后说个真实案例。我之前处理过一张日志表,每天进300万行,查询按时间范围加用户id过滤。刚开始直接insert然后裸查,慢到用户骂娘。后来改成:入库用load data,每天凌晨跑一次,白天只读。查询加复合索引(user_id, create_time),分页用延迟关联。结果导入时间从40分钟压到6分钟,单次查询从1.2秒降到80毫秒。没人夸你,但没人骂你,就是成功。 批量操作的核心就一句话:减少往返次数,让MySQL一次干更多的活。别迷信ORM,关键路径直接写SQL,性能提升是实打实的。
最近更新
热门排行
copyright © 2026 powered by 烟消火灭网   sitemap