MySQL 与EF 百万数据插入(汇总)

依次是:

方法一:循环插入(很慢)

方法二:一条sql语句n个insert

  通过合并SQL语句,同时也能减少SQL语句解析的次数,减少了数据库连接的I/O开销,一般会把多条数据插入放在一条SQL语句中一次执行;

  合并后日志量(MySQL的binlog和innodb的事务让日志)减少了,降低日志刷盘的数据量和频率,从而提高效率。

方法三:一个事务包裹n个insert

  因为进行一个INSERT操作时,MySQL内部会建立一个事务,在事务内才进行真正插入处理操作。通过使用事务可以减少创建事务的消耗,所有插入都在执行后才进行提交操作。

  读锁是共享的,它不会阻塞其他读锁;写锁是排他的,它会阻塞其他读锁和写锁;读读不互斥,读写互斥,写写互斥。这里读写互斥,应该说的是查询和修改互斥,因为实际测试发现:写入过程中可以查询,会看见行数在增加。

方法三:使用存储过程(内部也用事务包裹)

方法四:使用MYSQL LOCAL_INFILE

方法五:文件导入,用LOAD方法。 

 

优化:

*主键和索引列数据:有顺序插入。参照InnoDB使用的B+tree索引,如果每次插入记录都在索引的最后面,索引的定位效率很高,并且对索引调整较小;如果插入的记录在索引中间,需要B+tree进行分裂合并等处理,会消耗比较多计算资源,并且插入记录的索引定位效率会下降,数据量较大时会有频繁的磁盘操作。

*SQL语句是有长度限制,在进行数据合并在同一SQL中务必不能超过SQL长度限制,通过max_allowed_packet配置可以修改,默认是1M,测试时修改为8M。

*事务需要控制大小,事务太大可能会影响执行的效率。MySQL有innodb_log_buffer_size配置项,超过这个值会把innodb的数据刷到磁盘中,这时,效率会有所下降。所以比较好的做法是,在数据达到这个这个值前进行事务提交。

有前提条件的优化:

*当只有导入,没有查询和修改操作时。导入开始时可关闭唯一性校验 ,导入结束后执行,恢复唯一性校验。(未见测试效果)

SET  UNIQUE_CHECKS=0

insert...(导入语句)

SET  UNIQUE_CHECKS=1

类似的说法: 在确保数据无重复的前提下,导入数据前删除唯一索引,导入数据后恢复唯一索引。

*如果应用使用自动提交的方式,建议在导入前执行,关闭自动提交,导入结束后再开启。
SET AUTOCOMMIT=0

资料:

*mysql大批量插入数据四种方法

https://blog.csdn.net/qq_36324113/article/details/90610667

*大批量数据高效插入数据库表

https://www.cnblogs.com/myseries/p/11191134.html

*Mysql EF 数据录入&批量数据录入 (文件导入用load方法)

https://www.cnblogs.com/Lulus/p/12604595.html

https://www.cnblogs.com/ldj3/p/9287965.html

*SET  UNIQUE_CHECKS=0  问题的争议

http://blog.itpub.net/20892230/viewspace-2132317/

总结:不管是innodb,还是tokudb,只有在确认需要插入的数据的唯一性是可控的,或者不违反unique性,可以关闭unique_checks来提升性能.不过,还是那句老话,只有在确保数据的安全前提下,才考虑优化和性能提升的事儿.unique_checks对于数据的校验,还是启了很大的作用,所以.个人建议是不要关闭该参数.为了数据的安全.

https://www.cnblogs.com/zhouwanchun/p/13156459.html
首先,即便设置unique_checks=0,也无法往唯一索引中写入重复值。
其次,设置unique_checks=0的作用在于,批量导入数据(例如load data)时,在确保导入数据中无重复值时,无需再次检查其唯一性,加快导入速度。
所以,unique_checks=0并不是允许唯一约束失效,而是再批量导数据时不再逐行检查唯一性。

 

posted @ 2021-11-17 16:46  hao_1234_1234  阅读(336)  评论(0编辑  收藏  举报