暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

oracle迁移mysql后的性能问题竟然是字符集引起???

原创 jieguo 2022-09-27
1542

去O形式所逼,哪天您用mysql了,尤其是并发量大的情况下,您肯定也会遇到类似的性能问题,分享此记录仅供参考。

原库为oracle11.2.0.4,新mysql生产环境版本:MySQL 8.0.29+CentOS Linux release 7.4.1708 (Core)

mysql的源码安装可参考以前写过的一篇文章:https://www.modb.pro/db/450057

1.故障现象:

说实话mysql这块经验较少,用户要求分批迁移割接用户上线(一定用户量3000个后,系统性能明显扛不住了,所以暂时割接部分用户达可承受阶段)后发现原先在oracle上0.01秒执行的存储过程,在mysql竟然需要3以上秒,有时甚至50多秒。

2.故障分析:

看慢语句评估Rows_examined:25559(在2-3万条记录左右),明显走了全表扫描。如果走索引,自然不会超过2条。
image.png,但提取单条语句explain查看执行计划却是能走索引。
明显不正常,怀疑是否有参数配置不合适???
尝试分析相关表,并不起作用:analyze local table test_table;
image.png
只能继续baidu,google分析,根据上述的现象,参看了:https://baijiahao.baidu.com/s?id=1742728867212386956&wfr=spider&for=pc&qq-pf-to=pcqq.discussion
https://www.cnblogs.com/magicaltravel/p/7404936.html
我觉得就是字符集不匹配导致的不走索引。
image.png

相关知识:
image.png
查看当前的字符集配置:character_set_client,character_set_connection,character_set_server都是utf8mb3,而character_set_server是utf8mb4
image.png
查看表配置:其中字段是utf8,而表是utf8mb4
image.png
查看存储过程配置:
image.png

3.故障处理:

开发人员根据建议,做了相关调整测试:
mysql参数文件参考:(以后初始化就参考该参数文件即可)

[client]
port=3307
socket=/home/mysql/mysql.sock
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
port=3307
user=mysql
socket=/home/mysql/mysql.sock
basedir=/home/mysql/mysql
datadir=/home/mysql/data
lower-case-table-names=1 #不区分大小写
default_authentication_plugin=mysql_native_password
#skip-grant-tables
innodb_buffer_pool_size=100G #物理内存256G足够,根据情况调
slow_query_log=ON #开启记录慢日志
slow_query_log_file=/home/mysql/data/radiusp-slow.log #开启记录慢sql文件
long_query_time=2 #日志记录超过2秒的慢SQL
log_queries_not_using_indexes=off
max_connections=1000 #根据情况调
innodb_flush_log_at_trx_commit=2 #提升写性能,默认是1
skip-log-bin #单机没用到恢复,主从,所以取消
#以下最关键字符集设置
character_set_server=utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
skip-character-set-client-handshake = true

建库参考:

CREATE DATABASE testdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

建表参考(注意字段设置字符集):

CREATE TABLE test_table (
  `ACCTSESSIONID` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `LOGINNAME` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `RECDATE` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `NASPORT` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `FRAMEDIP` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  UNIQUE KEY `CURRSESSION_PK` (`ACCTSESSIONID`) USING BTREE,
  KEY `CURRSESSION_LOGINNAME` (`LOGINNAME`) USING BTREE,
  KEY `CURRSESSION_RECDATE` (`RECDATE`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC;

检查配置命令:

show variables like 'charater%';
show TABLE status like 'test_table' \G
show PROCEDURE status like 'P_TEST' \G
show create table test_table \G
show create PROCEDURE P_TEST \G

下图是最终正常结果:
image.png

4.处理结果:

最终0.01秒返回结果,效率极大提升从300~5000倍不等,不单是存储过程性能问题解决了,还有原先调用自定义函数的sql性能(改表字段字符集之前也超2秒)也正常了,慢语句不再出现。后续可安排割接更多用户到此环境了。
image.png
经过此次教训:发现mysql环境务必保证客户端、服务器端、库、表、字段等字符集设置一致,否则mysql优化器可能做隐式转换导致执行计划不正常,从而极大影响性能。

最后修改时间:2022-09-28 12:41:27
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论