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 /