尤川豪   ·  3月前
Exp. 1,708  ·  223 貼文  ·  153 留言

使用 MySQL 的編碼 utf8mb4_unicode_ci 在 JOIN 時遇到的效能問題

今天 debug 遇到一個效能問題,情境如下

資料表 Apple 的資料數約 11,000 筆,primary key 是一個 VARCHAR 欄位,以 utf8_unicode_ci 編碼

資料表 Banana 的資料數約 13,000 筆,有一個關聯到 Apple 的欄位 apple_id

資料表 Cat 的資料數約 16,000 筆,有一個關聯到表 Apple 的欄位 apple_id

進行兩個簡單的 JOIN 與 COUNT 查詢

select count(*) 
from bananas
left join apples
    on apples.id = bananas.apple_id
WHERE apples.xxx = 'yyy'
select count(*) 
from cats
left join apples
    on apples.id = cats.apple_id
WHERE apples.xxx = 'yyy'

SQL 內容很單純,資料量也不大。前者的執行時間是 8sec,後者是 200ms,差了40倍!

明明後者的資料量還比較大,怎麼會是前者比較慢?

debug 了半天,發現是 bananas 的 apple_id 欄位,編碼是 utf8mb4_unicode_ci。

原因是 bananas 資料表中,當初某個欄位需要能存表情符號,所以執行過

ALTER TABLE `bananas` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci

此舉一併把只是存關聯資料表 id 的欄位 apple_id 編碼一起改變了。

但是我沒想到會導致 JOIN 效能慢 40 倍。

花費不少時間,特此筆記一下。


問題:為什麼慢呢?

是 utf8mb4_unicode_ci 本來就比 utf8_unicode_ci 慢嗎?

還是 utf8mb4_unicode_ci 其實不慢,但 JOIN 的兩邊編碼不同,一邊 utf8_unicode_ci,一邊 utf8mb4_unicode_ci,所以才慢?

估計主要原因是後者。不過暫時先不研究這個主題了。

  分享   共 170 次點閱
共有 0 則留言
您的留言
尤川豪
Exp. 1,708  ·  223 貼文  ·  153 留言

關於作者

Devs.tw 作者,喜歡分享&建造新東西的工程師。

歡迎在 Facebook 追蹤我!不定期分享有趣技術文章!

  查看個人檔案