Kah*_*eng 998 mysql unicode collation utf-8 character-set
在utf8_general_ci和之间utf8_unicode_ci,性能方面有什么不同吗?
tho*_*ter 1514
这两个排序规则都是UTF-8字符编码.不同之处在于文本的排序和比较方式.
注意:从MySQL 5.5.3开始,你应该使用utf8mb4而不是utf8.它们都引用了UTF-8编码,但较旧版本utf8具有MySQL特定的限制,阻止使用编号高于0xFFFD的字符.
准确性
utf8mb4_0900_ai_ci 基于Unicode标准进行排序和比较,可以在各种语言中进行准确排序.
general 无法实现所有Unicode排序规则,这将在某些情况下导致不合需要的排序,例如使用特定语言或字符时.
性能
utf8mb4_unicode_ci 在比较和排序方面更快,因为它需要一堆与性能相关的快捷方式.
在现代服务器上,这种性能提升几乎可以忽略不计.它是在服务器只占当今计算机CPU性能的一小部分时设计的.
utf8mb4_general_ci,它使用Unicode规则进行排序和比较,使用相当复杂的算法在各种语言中进行正确排序,并且在使用各种特殊字符时.这些规则需要考虑特定语言的惯例; 不是每个人都按照我们称之为"字母顺序"的方式对他们的角色进行排序.
就拉丁语(即"欧洲")语言而言,utf8mb4_unicode_ciMySQL 排序和MySQL中的简化排序没有太大区别,但仍存在一些差异:
例如,Unicode排序规则将"ß"排序为"ss",将"Œ" utf8mb4_0900_ai_ci排序为"OE",因为使用这些字符的人通常会想要,而将它们排序为单个字符(可能分别称为"s"和"e") .
某些Unicode字符被定义为可忽略,这意味着它们不应计入排序顺序,而比较应转移到下一个字符. 0900正确处理这些.
在非拉丁语言中,例如亚洲语言或具有不同字母表的语言,Unicode排序和简化排序之间可能存在更多差异ai.适用性在utf8mb4_unicode_ci很大程度上取决于所使用的语言.对于某些语言来说,这将是非常不合适的.
你应该用什么?
几乎可以肯定没有理由再使用utf8mb4_unicode_ci,因为我们已经落后于CPU速度足够低以至于性能差异很重要的地步.您的数据库几乎肯定会受到其他瓶颈的限制.
性能上的差异只能在非常特殊的情况下才能衡量,如果是你,你可能已经知道了.如果您遇到的排序速度很慢,几乎在所有情况下都会出现索引/查询计划的问题.在要排除故障的事项列表中,更改排序规则功能不应该很高.
在过去,有些人建议使用,utf8mb4_general_ci除非准确的排序对于确定性能成本是非常重要的.今天,性能成本几乎消失了,开发人员正在更加认真地对待国际化.
我要补充的另一件事是,即使您知道您的应用程序仅支持英语,它仍可能需要处理人名,这通常包含其他语言中使用的字符,其中正确排序同样重要.对所有内容使用Unicode规则有助于让非常聪明的Unicode人员非常努力地使排序正常工作.
nig*_*der 154
我想知道使用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;
Run Code Online (Sandbox Code Playgroud)
然后我通过运行这个存储过程填充随机数据:
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
Run Code Online (Sandbox Code Playgroud)
然后我创建了以下存储过程来对simple SELECT,SELECTwith LIKE和sort(SELECTwith 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;
Run Code Online (Sandbox Code Playgroud)
在上面的存储过程utf8_general_ci中使用了排序规则,但当然在测试期间我使用了utf8_general_ci和utf8_unicode_ci.
我为每个排序规则调用了每个存储过程5次(5次utf8_general_ci,5次utf8_unicode_ci),然后计算平均值.
我的结果是:
benchmark_simple_select()
utf8_general_ci:9,957毫秒 utf8_unicode_ci:10,271毫秒 在这个基准测试中使用utf8_unicode_ci比慢于utf8_general_ci3.2%.
benchmark_select_like()
utf8_general_ci:11,441毫秒 utf8_unicode_ci:12,811毫秒 在这个基准测试中,使用utf8_unicode_ci速度慢于utf8_general_ci12%.
benchmark_order_by()
utf8_general_ci:11,944毫秒 utf8_unicode_ci:12,887毫秒 在此基准测试中,使用utf8_unicode_ci速度比utf8_general_ci7.9%慢.
Ada*_*dam 12
排序和字符匹配有两个很大的区别:
\n\n排序:
\n\nutf8mb4_general_ci删除所有重音符号并进行一一排序,这可能会产生不正确的排序结果。utf8mb4_unicode_ci排序准确。字符匹配
\n\n它们以不同的方式匹配字符。
\n\n例如,utf8mb4_unicode_ci你有i != \xc4\xb1,但utf8mb4_general_ci它包含\xc4\xb1=i。
例如,假设您有一行name="Y\xc4\xb1lmaz". 然后
select id from users where name=\'Yilmaz\';\nRun Code Online (Sandbox Code Playgroud)\n\n如果搭配是 则返回该行,但如果它与它utf8mb4_general_ci搭配则不会utf8mb4_unicode_ci返回该行!
另一方面,我们有 thata=\xc2\xaa和\xc3\x9f=ssin utf8mb4_unicode_ciwhich ,但情况并非如此utf8mb4_general_ci。所以想象一下你和name="\xc2\xaa\xc3\x9fi",然后
select id from users where name=\'assi\';\nRun Code Online (Sandbox Code Playgroud)\n\n如果 collocation 为 则返回行utf8mb4_unicode_ci,但如果 collocation 设置为 则不会返回行utf8mb4_general_ci。
可以在此处找到每种搭配的完整匹配列表。
\n请参阅mysql手册,Unicode字符集部分:
对于任何Unicode字符集,使用_general_ci排序规则执行的操作比_unicode_ci排序规则更快.例如,与utf8_unicode_ci的比较相比,utf8_general_ci整理的比较更快,但更不正确.原因是utf8_unicode_ci支持扩展等映射; 也就是说,当一个字符与其他字符的组合相等时.例如,在德语和其他一些语言中,"ß"等于"ss".utf8_unicode_ci还支持收缩和可忽略的字符.utf8_general_ci是一种遗留的排序规则,不支持扩展,收缩或可忽略的字符.它只能在字符之间进行一对一的比较.
总而言之,utf_general_ci使用比utf_unicode_更小且更不正确(根据标准)的比较集,其应该实现整个标准.general_ci集会更快,因为计算量较少.
正如我们在这里读到的(彼得古鲁赞),在排序/比较波兰语字母“?”方面存在差异。(L withstroke - 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
Run Code Online (Sandbox Code Playgroud)
在波兰语中,字母?在字母之后L和之前M。这些编码没有一个更好或更坏 - 这取决于您的需求。
简而言之:
如果您需要更好的排序顺序 - 使用utf8_unicode_ci(这是首选方法),
但如果你对性能完全感兴趣 - 使用utf8_general_ci,但要知道它有点过时了.
性能方面的差异非常小.
| 归档时间: |
|
| 查看次数: |
379457 次 |
| 最近记录: |