arl*_*dia 3 php mysql unicode database-performance
我的PHP Web应用程序中的所有MySQL表都是具有utf8编码的MyISAM。由于可以在离线状态下通过配套应用生成记录,因此我的表键是随机生成的字母数字VARCHAR;这些字段使用utf8_bin编码设置为二进制,因此它们区分大小写。
我最近决定更改我所有文本字段的编码,以支持某些用户喜欢输入的表情符号。我继续将所有utf8字段更改为utf8mb4,包括密钥。我立即开始发现性能问题,其中对一个较大的表进行复杂的SELECT查询要花费一分钟多的时间,然后其他查询排队等待表锁。我将该表上的主键字段的编码改回了utf8,性能恢复了正常。几天后,我再次将该字段更改为utf8mb4,查询再次开始排队,然后将其更改为恢复正常性能。
因此,运行顺利:
`ID` varchar(8) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''
Run Code Online (Sandbox Code Playgroud)
但这会导致问题:
`ID` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT ''
Run Code Online (Sandbox Code Playgroud)
我读过的所有内容都说utf8和utf8mb4应该具有同等的性能,但是我发现我的情况有明显的不同。这有意义吗?
将关键字段保留在utf8并不是一个真正的问题,因为我预见在那里不会再使用简单的字母数字字符。但是我希望将所有字段都设置为相同的编码,只是为了保持一致和简化维护(不必记住将用户填充的字段设置为一种编码,而将关键字段设置为另一种编码)。
关于@MandyShaw的评论
当我使用Sequel Pro Mac应用程序处理数据库时,控制台会不断显示成对的SET NAMES 'utf8'和SET NAMES 'utf8mb4'条目,因此这表明并非所有设置都正确。但是,这是我目前所拥有的:
MySQL [(none)]> SHOW GLOBAL VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+
Run Code Online (Sandbox Code Playgroud)
我读到它character_set_system不能从utf8更改,character_set_filesystem应该是二进制的。
Sequel Pro的连接编码设置为“自动检测”,但是当我将其明确更改为utf8mb4,然后打开一个新连接时,我仍然在控制台中看到所有这些编码更改。
我需要更改其他内容以一致地使用此编码吗?
utf实际上是utfmb3,每个字符最多可以使用3个字节,而utfmb4每个字符最多可以使用4个字节。对于VARCHAR列,这通常没有太大区别,因为MySQL将仅存储所需的字节数(除非您使用ROW_FORMAT = FIXED创建了MyISAM表)。
但是,在查询执行期间,MySQL可能会在不支持可变长度行的MEMORY存储引擎中创建临时表。这些临时表具有最大大小,如果超过该大小,则临时表将转换为MyISAM / InnoDB中的表(取决于您的MySQL版本)。Created_tmp_disk_tables每次发生这种情况,状态变量都会增加。如果是这样,尝试,看它是否有助于增加的价值max_heap_table_size 和 tmp_table_size。
或者,升级到MySQL 8.0,其中将支持可变长度行的新存储引擎用于内部临时表。
| 归档时间: |
|
| 查看次数: |
998 次 |
| 最近记录: |