为何MySQL(MariaDB)日志中反复出现SET NAMES UTF8语句?
问题分析:为何导入脚本反复执行SET NAMES UTF8?
问题背景
某PHP脚本从CSV文件导入数据到数据库,在MariaDB 10.5.22上运行耗时约10分钟,远慢于在MySQL 5.6上的约1分钟。排查时发现通用日志中反复出现「连接数据库→执行SET NAMES UTF8→断开连接」的循环操作。
通用日志内容
4332471 Connect myuser@10.20.30.40 on mydatabase using TCP/IP 4332471 Query SET NAMES UTF8 4332471 Quit 4332472 Connect myuser@10.20.30.40 on mydatabase using TCP/IP 4332472 Query SET NAMES UTF8 4332472 Quit 4332473 Connect myuser@10.20.30.40 on mydatabase using TCP/IP 4332473 Query SET NAMES UTF8 4332473 Quit
慢查询日志片段
SET timestamp=1720100123; # administrator command: Quit; # Time: 240704 14:35:24 # User@Host: myuser[myuser] @ [10.20.30.40] # Thread_id: 1801710 Schema: mydatabase QC_hit: No # Query_time: 0.000044 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 # Rows_affected: 0 Bytes_sent: 11 use mydatabase; SET timestamp=1720100124; SET NAMES UTF8; # User@Host: myuser[myuser] @ [10.20.30.40] # Thread_id: 1801710 Schema: mydatabase QC_hit: No # Query_time: 0.000001 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 # Rows_affected: 0 Bytes_sent: 0 SET timestamp=1720100124; # administrator command: Quit; # User@Host: myuser[myuser] @ [10.20.30.40] # Thread_id: 1801711 Schema: mydatabase QC_hit: No # Query_time: 0.000021 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 # Rows_affected: 0 Bytes_sent: 11 SET timestamp=1720100124; SET NAMES UTF8;
当前数据库排序规则配置
+----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | utf8_general_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+ +--------------------------+----------------------+ | @@character_set_database | @@collation_database | +--------------------------+----------------------+ | utf8 | utf8_bin | +--------------------------+----------------------+
原因解析
- 脚本连接模式不合理:PHP脚本大概率在处理每条(或每小批)数据后就关闭了数据库连接,下一次处理时重新建立连接。而PHP的数据库驱动(如mysqli、PDO)默认会在每次连接建立后执行
SET NAMES UTF8,确保应用与数据库的字符集一致,这是日志中反复出现该语句的直接原因。 - 字符集层级配置不统一:服务器级排序规则是
latin1_swedish_ci,但数据库级字符集为utf8、排序规则为utf8_bin,连接级又使用utf8_general_ci。这种多层级的字符集/排序规则不匹配,导致驱动必须显式执行SET NAMES来覆盖默认配置,避免数据乱码。 - MariaDB与MySQL的连接开销差异:MariaDB 10.5相比MySQL 5.6,连接建立的开销更高(比如认证流程、线程管理机制的变化)。反复创建和销毁连接的累积开销,直接导致了导入速度的大幅下降——MySQL 5.6连接开销低,多次连接的影响不明显,因此速度更快。
内容的提问来源于stack exchange,提问作者Confounder
相关产品推荐
相关产品推荐

