【发布时间】:2010-09-11 18:32:47
【问题描述】:
我有通过 ODBC 访问 MySQL 的 C# 代码。
它创建一个事务,执行几千个插入命令,然后提交。 现在我的问题是有多少“往返”,可以这么说,发生在数据库服务器上?我的意思是,它只是将每个插入命令传输到数据库服务器,还是缓存/缓冲它们并分批发送?这是否可以以任何方式配置?
【问题讨论】:
我有通过 ODBC 访问 MySQL 的 C# 代码。
它创建一个事务,执行几千个插入命令,然后提交。 现在我的问题是有多少“往返”,可以这么说,发生在数据库服务器上?我的意思是,它只是将每个插入命令传输到数据库服务器,还是缓存/缓冲它们并分批发送?这是否可以以任何方式配置?
【问题讨论】:
没有看到您的代码很难说,但我假设您一次执行一个语句。因此,每个插入语句将获得一次往返。
在 MSSql 中,您可以在单个语句中执行多个插入:
cmd.ExecuteNonQuery "insert table values (1) insert table values (2)"
所以你可以创建一个大字符串并执行它(我认为它会有一个限制),我认为这适用于 MySQL。
此外,在 MSSQL 中,您有一个批处理插入器(查找“SqlBulkCopy”),在 MySQL 中也许可以尝试 loading the data from a temp file。
【讨论】:
您提交的每个查询都会执行一次往返(无论它是否在事务中)。
在 MySQL 中,可以使用“扩展插入”语法,它允许您在单个语句中插入多个(或者实际上是许多)行。这通常被认为是一件好事。
【讨论】:
几年前使用 MySQL 4.x 时,我们遇到了不可配置的查询大小的硬限制。
这可能对您没有多大帮助:
祝你好运!
【讨论】:
往返于数据库服务器与往返于磁盘上的数据库不同。
在您确定往返行程是瓶颈之前,请进行一些实际测量。
有多种方法可以通过一次插入来插入多行,具体取决于您的 DBMS。在您投入编码工作之前,请弄清楚它是否可能对您有任何好处。
【讨论】:
MySQL 有一个可以使用的扩展 SQL 样式,其中一次放入多个批量插入:
INSERT INTO `table` (`id`, `event`) VALUES (1, 94263), (2, 75015), (3, 75015);
在运行 SQL 查询本身之前,我通常会将几百个插入部分收集到一个字符串中。这将通过自己对它们进行批处理来减少解析和通信的开销。
【讨论】:
这取决于您调用 SQL 语句的位置。我用 MySQL JDBC 驱动程序尝试过一次,得到一个错误,说限制是 1MB,但它是可配置的。
我没有费心去尝试配置它,只是将 SQL 语句分成更小的部分。
【讨论】:
本身的行数没有限制;限制是传输到服务器的字节数。
您可以将批量插入构建到“最大允许数据包”中指定的字节数。如果我想使用最少的插入量,我会尝试。
【讨论】:
将发送的数据限制取决于您的服务器,因此多个插入语句的最大长度会自动调整以适应。瓶颈是数据包长度和缓冲区长度。
有关详细信息,请参阅 net_buffer_length 和 max_allowed_packet 变量说明:
https://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_net_buffer_length https://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_max_allowed_packet
在某些情况下,您可以调整这些(例如,在转储数据时)以不生成太长但保留多个插入的插入。请注意,如果您的表中有一些 blob 或任何其他可能超过上述变量值的长值,您可能会收到错误或不完整的数据。
【讨论】: