网站开发周志,优秀个人网站图片,移动论坛网站模板免费下载,电商网站开发思路文章目录 1.背景2.问题3.分批插入4.一次最多能插入多少条记录#xff1f;参考文献 1.背景
Golang 后台服务使用 GORM 实现与 MySQL 的交互#xff0c;在实现一个通过 Excel 导入数据的接口时#xff0c;使用 Save 方法一次性插入大量记录#xff08;1w#xff09;时报… 文章目录 1.背景2.问题3.分批插入4.一次最多能插入多少条记录参考文献 1.背景
Golang 后台服务使用 GORM 实现与 MySQL 的交互在实现一个通过 Excel 导入数据的接口时使用 Save 方法一次性插入大量记录1w时报了如下错误
Error 1390 (HY000): Prepared statement contains too many placeholders2.问题
在 MySQL 官方文档 Server Error Message Reference 可以看到其描述。 该错误属于 MySQL 服务端错误可惜的是官方文档并未给出详细的错误原因只给出了错误码的简短描述。错误描述字面意思是“预处理语句包含太多占位符”结合业务场景猜测原因是一次插入太多记录。
3.分批插入
既然不允许一次插入太多记录那么可以改为分批插入而不是一次性插入所有数据。
// 待插入的记录。
records : parseRecordsFromExcel()
batch : 1000for i : 0; i len(records ); i batch {end : i batchif end len(records) {end len(record)}return Db.Save(records[i:end]).Error
}正如预期的那样改为分批插入解决了问题。
不知道你有没有疑问我这里分批插入每批记录数是 1000那可以采用 2000 或者其他数量吗每批插入记录数的上限是多少呢
带着这个疑问请继续往下看。
4.一次最多能插入多少条记录
MySQL 服务端之所以报 Error 1390 (HY000) 错误原因是不允许一次插入过多的记录。更深层次的原因是 MySQL SQL 语句的占位符数量有上限最大值为 16bits 无符号整数的最大值65535。
可以在 sql/sql_prepare.cc 中看到相关代码
static bool init_param_array(THD *thd, Prepared_statement *stmt) {LEX *lex stmt-m_lex;if ((stmt-m_param_count lex-param_list.elements)) {if (stmt-m_param_count static_castuint(UINT_MAX16)) {/* Error code to be defined in 5.0 */my_error(ER_PS_MANY_PARAM, MYF(0));return true;}...
}如果是 INSERT 语句插入 n 条记录每条记录有 m 列则要求 m*n 65535。
如果数据量很大最简单的解决方法就是进行分批插入。
参考文献
Chapter 2 Server Error Message Reference How many bind variables can I use in a SQL query in MySQL 5?