如何计算 MySQL 语句的大小(不是查询结果)

How calculate the size of a MySQL statement (not the query results)

我正在开发一种针对 MySQL 数据库生成和运行 SQL 的工具。我正在尝试添加根据用户指定的设置限制插入语句大小的功能。我找到了一些关于 max_allowed_packet 设置的信息,但我还没有找到任何解释如何计算数据包大小的信息。 MySQL 文档说 "A communication packet is a single SQL statement sent to the MySQL server," 但我不明白 SQL 语句的大小是如何确定的。

我正在向驱动程序传递 SQL 语句和一些参数:

cmd.CommandText= "INSERT INTO myTable VALUES(@int, @date, @text)";
cmd.Parameters.AddWithValue("@int", 1);
cmd.Parameters.AddWithValue("@date", DateTime.Now);
cmd.Parameters.AddWithValue("@text", "how big is this???");
cmd.ExecuteNonQuery();

数据包的大小是否只是所有变量的字符串表示和SQL语句中使用的字节的总和?或者我应该根据每个参数在数据库中占用多少 space 来计算每个参数的大小,并将其与 SQL 字符串中使用的字节相加?或者是其他东西?我不太确定数据库驱动程序是如何工作的,所以如果您对它们有所了解,那么一些相关的上下文可能会有所帮助。

我对 MySql max_packet_allowed 中定义的数据包大小的理解来自文档。我花了一些时间寻找明确的答案,但没有成功。所以我假设我的回答是正确的,但是 YMMV 和你可能仍然 运行 有问题。

You must increase [max_packet_allowed] value if you are using large BLOB columns or long strings. It should be as big as the largest BLOB you want to use. The protocol limit for max_allowed_packet is 1GB. The value should be a multiple of 1024; nonmultiples are rounded down to the nearest multiple.

以上引用来自 https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_max_allowed_packet 的 v5.5 文档。

根据语句 "it should be as big as the largest BLOB you want to use",我 推断 max_packet_size 基于列大小,而不是 sql 语句大小。列数据大小将取决于内容和编码。检查您的字符集和排序规则设置,了解您使用的是每个字符 2 字节还是 4 字节。

验证它是语句大小还是列大小的一种简单方法是使用带有两个文本列的简单 table。假设你的max_packet_allowed在客户端和服务端都是16M。 运行 一条插入语句,其中一列是 8M,另一列是 10M(总共 18M)。如果语句失败 运行,则为语句大小。如果没有失败,您可以假设它基于列大小。

当您根据 max_packet_allowed 实施数据包大小检查时,请务必记住服务器和客户端都设置了此值。以较低者为准。因为客户端可以设置它,所以你不能假设它们总是相同的。

如果提供了更多参考资料来纠正信息,我非常乐意编辑此答案。如果我离题太远,我会很乐意删除答案。

原来 max_allowed_packet 与以 ASCII 编码通过线路发送的结果查询的大小进行了比较。我只是将参数值替换为 SQL 语句而不是参数名称,并获取了结果字符串的大小。字节数是 MySQL 是否会拒绝该语句的准确预测,因此我可以根据该数字确定何时开始新语句。