去O形式所逼,哪天您用mysql了,尤其是并發量大的情況下,您肯定也會遇到類似的性能問題,分享此記錄僅供參考。
原庫為oracle11.2.0.4,新mysql生產環境版本:MySQL 8.0.29+CentOS Linux release 7.4.1708 (Core)
mysql的源碼安裝可參考以前寫過的一篇文章:http://www.sunline.cc/db/450057
1.故障現象:
說實話mysql這塊經驗較少,用戶要求分批遷移割接用戶上線(一定用戶量3000個后,系統性能明顯扛不住了,所以暫時割接部分用戶達可承受階段)后發現原先在oracle上0.01秒執行的存儲過程,在mysql竟然需要3以上秒,有時甚至50多秒。
2.故障分析:
看慢語句評估Rows_examined:25559(在2-3萬條記錄左右),明顯走了全表掃描。如果走索引,自然不會超過2條。
,但提取單條語句explain查看執行計劃卻是能走索引。
明顯不正常,懷疑是否有參數配置不合適???
嘗試分析相關表,并不起作用:analyze local table test_table;

只能繼續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
我覺得就是字符集不匹配導致的不走索引。

相關知識:

查看當前的字符集配置:character_set_client,character_set_connection,character_set_server都是utf8mb3,而character_set_server是utf8mb4

查看表配置:其中字段是utf8,而表是utf8mb4

查看存儲過程配置:

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
下圖是最終正常結果:

4.處理結果:
最終0.01秒返回結果,效率極大提升從300~5000倍不等,不單是存儲過程性能問題解決了,還有原先調用自定義函數的sql性能(改表字段字符集之前也超2秒)也正常了,慢語句不再出現。后續可安排割接更多用戶到此環境了。

經過此次教訓:發現mysql環境務必保證客戶端、服務器端、庫、表、字段等字符集設置一致,否則mysql優化器可能做隱式轉換導致執行計劃不正常,從而極大影響性能。




