utf8_general_ci
和utf8_unicode_ci
,在性能方面是否存在差別? php
我想知道utf8_general_ci
和utf8_unicode_ci
之間的性能差別是什麼,可是我沒有在互聯網上找到任何基準,所以我決定本身建立基準。 html
我建立了一個具備500,000行的很是簡單的表: mysql
CREATE TABLE test( ID INT(11) DEFAULT NULL, Description VARCHAR(20) DEFAULT NULL ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;
而後,我經過運行此存儲過程將其填充爲隨機數據: 算法
CREATE PROCEDURE randomizer() BEGIN DECLARE i INT DEFAULT 0; DECLARE random CHAR(20) ; theloop: loop SET random = CONV(FLOOR(RAND() * 99999999999999), 20, 36); INSERT INTO test VALUES (i+1, random); SET i=i+1; IF i = 500000 THEN LEAVE theloop; END IF; END LOOP theloop; END
而後,我建立了如下存儲過程來對簡單的SELECT
, SELECT
與LIKE
和排序( SELECT
與ORDER BY
)進行基準測試: sql
CREATE PROCEDURE benchmark_simple_select() BEGIN DECLARE i INT DEFAULT 0; theloop: loop SELECT * FROM test WHERE Description = 'test' COLLATE utf8_general_ci; SET i = i + 1; IF i = 30 THEN LEAVE theloop; END IF; END LOOP theloop; END; CREATE PROCEDURE benchmark_select_like() BEGIN DECLARE i INT DEFAULT 0; theloop: loop SELECT * FROM test WHERE Description LIKE '%test' COLLATE utf8_general_ci; SET i = i + 1; IF i = 30 THEN LEAVE theloop; END IF; END LOOP theloop; END; CREATE PROCEDURE benchmark_order_by() BEGIN DECLARE i INT DEFAULT 0; theloop: loop SELECT * FROM test WHERE ID > FLOOR(1 + RAND() * (400000 - 1)) ORDER BY Description COLLATE utf8_general_ci LIMIT 1000; SET i = i + 1; IF i = 10 THEN LEAVE theloop; END IF; END LOOP theloop; END;
在上面的存儲過程當中,使用了utf8_general_ci
歸類,可是固然在測試期間,我同時使用了utf8_general_ci
和utf8_unicode_ci
。 less
對於每一個排序規則,我分別對每一個存儲過程調用5次(對於utf8_general_ci
, utf8_unicode_ci
5次,對於utf8_unicode_ci
, utf8_unicode_ci
5次),而後計算平均值。 dom
個人結果是: oop
benchmark_simple_select()
性能
utf8_general_ci
:9,957毫秒 utf8_unicode_ci
:10,271毫秒 在此基準測試中,使用utf8_unicode_ci
比utf8_general_ci
慢3.2%。 測試
benchmark_select_like()
utf8_general_ci
:11,441毫秒 utf8_unicode_ci
:12,811毫秒 在此基準測試中,使用utf8_unicode_ci
比utf8_general_ci
慢12%。
benchmark_order_by()
utf8_general_ci
:11,944毫秒 utf8_unicode_ci
:12,887毫秒 在此基準測試中,使用utf8_unicode_ci
比utf8_general_ci
慢7.9%。
這篇文章很好地描述了它。
簡而言之:utf8_unicode_ci使用Unicode標準中定義的Unicode排序算法,而utf8_general_ci是更簡單的排序順序,致使「不太準確」的排序結果。
簡而言之:
若是您須要更好的排序順序,請使用utf8_unicode_ci
(這是首選方法),
但若是您對性能徹底感興趣,請使用utf8_general_ci
,但要知道它有點過期了。
在性能方面的差別很小。
正如咱們在這裏能夠讀到的( Peter Gulutzan ),對波蘭字母「Ł」進行排序/比較(帶筆觸的L-html esc: Ł
)(小寫:「ł」-html esc: ł
)有所不一樣-咱們有如下假設:
utf8_polish_ci Ł greater than L and less than M utf8_unicode_ci Ł greater than L and less than M utf8_unicode_520_ci Ł equal to L utf8_general_ci Ł greater than Z
在波蘭語中,字母Ł
在字母L
和M
以前。 這種編碼的好與壞都沒有,這取決於您的需求。
根據這篇文章,使用utf8mb4_general_ci代替utf8mb4_unicode_ci時,在MySQL 5.7上有至關大的性能優點: https ://www.percona.com/blog/2019/02/27/charset-and-collation-settings-impact -關於mysql-performance /