1. 程式人生 > 其它 >mysql 取出最後一個字元_MySQL一個字符集轉換的騷操作,釀下效能的苦果

mysql 取出最後一個字元_MySQL一個字符集轉換的騷操作,釀下效能的苦果

技術標籤:mysql 取出最後一個字元

這是學習筆記的第 2275篇文章

990156d8fe71af2b8cde379ced51fa0c.gif

今天處理了一個RDS的問題,突然想起了好幾年前處理的一個性能案例,看似不經意的細節竟然讓我對整個問題的過程有了更清晰的認識。

整個細節可以參見我寫的這篇文章的處理過程:

力薦:一條update語句引發的“血案”

當時有一個地方沒有想明白,那就是裡面的欄位APNS_PUSH_ID為什麼字符集會是latin1,而表的字符集卻妥妥的是UTF8,看起來是一個不大可能出現的場景。

c88139d9aeb99123133d02433076b9c6.png

下午在協助處理一個問題的時候,才突然明白,我來複現下這個問題。

建立一張表test_charset,設定字符集為latin1

mysql> create table test_charset(id int primary key,name varchar(30),memo varchar(30)) charset=latin1;
Query OK, 0 rows affected (0.12 sec)

查看錶結構,可以清晰的看到,欄位是共享了表的預設字符集,沒有顯式顯示出來。

mysql> show create table test_charsetG*************************** 1. row *************************** Table: test_charsetCreate Table: CREATE TABLE `test_charset` ( `id` int(11) NOT , `name` varchar(30) DEFAULT , `memo` varchar(30) DEFAULT ,
PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin11 row in set (0.01 sec)

我們使用如下的語句來變更下表的字符集。

mysql> alter table test_charset charset=utf8;Query OK, 0 rows affected (0.05 sec)Records: 0 Duplicates: 0 Warnings: 0

這個時候再次檢視就會發現,原本“繼承”的latin1字符集現在顯式顯示出來了,表的字符集是utf8,但是字元型別的欄位字符集依然是latin1

mysql> show create table test_charsetG
*************************** 1. row *************************** Table: test_charsetCreate Table: CREATE TABLE `test_charset` ( `id` int(11) NOT , `name` varchar(30) CHARACTER SET latin1 DEFAULT , `memo` varchar(30) CHARACTER SET latin1 DEFAULT , PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)

如果後續再新增欄位,不顯式指定字符集。

mysql> alter table test_charset add memo2 varchar(30);Query OK, 0 rows affected (0.14 sec)Records: 0 Duplicates: 0 Warnings: 0

查看錶結構會發現,新欄位memo2的字符集就會是utf8

mysql> show create table test_charsetG*************************** 1. row *************************** Table: test_charsetCreate Table: CREATE TABLE `test_charset` ( `id` int(11) NOT , `name` varchar(30) CHARACTER SET latin1 DEFAULT , `memo` varchar(30) CHARACTER SET latin1 DEFAULT , `memo2` varchar(30) DEFAULT , PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)

好了,問題到了這裡就相對有了一個思路。

那麼產生最開始讓人疑惑的問題原因是什麼呢?就是哪個騷操作:

mysql> alter table test_charset charset=utf8;

這是一個表級屬性的變更,注意MySQL裡面欄位,表,資料庫都可以存在差異化的字符集設定。雖然可以支援,但是顯然這樣做是不合理的。

而如果要讓欄位的變更同時生效,應該使用convert to 語句,我們為了突出變化,改為utf8mb4字符集。

mysql> alter table test_charset convert to charset utf8mb4; Query OK, 0 rows affected (0.13 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> show create table test_charsetG*************************** 1. row *************************** Table: test_charsetCreate Table: CREATE TABLE `test_charset` ( `id` int(11) NOT , `name` varchar(30) DEFAULT , `memo` varchar(30) DEFAULT , `memo2` varchar(30) DEFAULT , PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb41 row in set (0.00 sec)