【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
utf8_general_ci
和utf8_unicode_ci
,在性能方面是否存在差异?
#1楼
我想知道utf8_general_ci
和utf8_unicode_ci
之间的性能差异是什么,但是我没有在互联网上找到任何基准,因此我决定自己创建基准。
我创建了一个具有500,000行的非常简单的表:
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
)进行基准测试:
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
。
对于每个排序规则,我分别对每个存储过程调用5次(对于utf8_general_ci
, utf8_unicode_ci
5次,对于utf8_unicode_ci
, utf8_unicode_ci
5次),然后计算平均值。
我的结果是:
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%。
#2楼
这篇文章很好地描述了它。
简而言之:utf8_unicode_ci使用Unicode标准中定义的Unicode排序算法,而utf8_general_ci是更简单的排序顺序,导致“不太准确”的排序结果。
#3楼
简而言之:
如果您需要更好的排序顺序,请使用utf8_unicode_ci
(这是首选方法),
但如果您对性能完全感兴趣,请使用utf8_general_ci
,但要知道它有点过时了。
在性能方面的差异很小。
#4楼
一些细节(PL)
正如我们在这里可以读到的( 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
之前。 这种编码的好与坏都没有,这取决于您的需求。
#5楼
根据这篇文章,使用utf8mb4_general_ci代替utf8mb4_unicode_ci时,在MySQL 5.7上有相当大的性能优势: https ://www.percona.com/blog/2019/02/27/charset-and-collation-settings-impact -关于mysql-performance /
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3142811