mysql 查找查询的大小

qzwqbdag  于 2023-02-03  发布在  Mysql
关注(0)|答案(2)|浏览(104)

基于MySQL中的max_allowed_packet配置参数,我很想知道如何确定与该特定配置相关的查询的大小?
我们可以在MySQL服务器中使用SHOW VARIABLES LIKE 'max_allowed_packet'命令,这将提供参数的当前值,然后可以使用该值相应地计算查询的大小。此外,还可以使用SET GLOBAL max_allowed_packet命令设置参数的新值。
我的问题是:如何计算与此配置相比的查询大小?

n6lpvg4x

n6lpvg4x1#

数据包的MariaDB protocol documentation声明客户端发送的每个数据包必须低于max_allowed_packet限制。这意味着所有SQL查询必须短于max_allowed_packet。在大多数情况下,除非您使用SQL语句插入大量数据,否则您不必担心这一点。
由于网络数据包中存在一些开销,所以对于长度小于16 Mib的查询,一个好的经验法则是将查询的字符串长度(以字节为单位)减去1个字节:数据包报头的长度将是SQL查询加上COM_QUERY字节。一般来说,为了匹配限制而走到这一步是不值得的,保持在限制之下往往是更实用的方法。
这并不意味着服务器不会生成比这个长度更长的数据包。下面是一个服务器超过max_allowed_packet限制的示例:

MariaDB [test]> SET @a = (SELECT GROUP_CONCAT(seq) FROM seq_0_to_1000000);
Query OK, 0 rows affected, 1 warning (0.060 sec)

MariaDB [test]> SELECT LENGTH(@a), @@max_allowed_packet, @@group_concat_max_len;
+------------+----------------------+------------------------+
| LENGTH(@a) | @@max_allowed_packet | @@group_concat_max_len |
+------------+----------------------+------------------------+
|    1048576 |                16384 |                1048576 |
+------------+----------------------+------------------------+
1 row in set (0.001 sec)
 
MariaDB [test]> SELECT LENGTH(@a), @a\G
*************************** 1. row ***************************
LENGTH(@a): 1048576
        @a: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
... More data ...

max_allowed_packet的值与结果集的大小也没有多大关系。如果将max_allowed_packet设置为16 Kib,则可以生成TB大小的结果。这是因为结果集是一个数据包流,如果每个数据包都低于限制,则结果集的长度没有限制。
正如Georg Richter在注解中提到的,@max_allowed_packet也会影响一些文字/字符串的长度,例如,即使实际SQL语句的字符串长度只有几个字节,SET @a:= REPEAT("A", @@max_allowed_packet + 1)也会失败。

0tdrvxhp

0tdrvxhp2#

要在数据库中100%完成此操作,您可以根据查询结果创建一个表:

CREATE TABLE db_name.test_table SELECT a v1, b v2 FROM db_name.tbl2;

您希望其结果大小的查询应替换为

SELECT a v1, b v2 FROM db_name.tbl2

然后获取表的大小

SELECT round((data_length / 1024 / 1024), 2) "Size in MB" 
      FROM information_schema.TABLES 
    WHERE table_schema = "db_name" AND table_name = "test_table";

然后放下测试台:

drop table db_name.test_table;

这只会给予原始数据的大小,而不会有任何额外的开销,比如传输回来的数据包头(如果您的结果集被分成许多包)。
甚至可能有一种聪明的方法可以使用临时表或在存储过程中传递查询。
之后,您可以在select中获取全局变量以进行比较

SELECT
  variable_name,
  variable_value
FROM information_schema.global_variables
WHERE variable_name LIKE  'max_allowed_packet';

相关问题