utf8_general_ci和utf8_unicode_ci有什么区别

感情迁移 提交于 2019-12-13 20:20:06

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

utf8_general_ciutf8_unicode_ci ,在性能方面是否存在差异?


#1楼

我想知道utf8_general_ciutf8_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

然后,我创建了以下存储过程来对简单的SELECTSELECTLIKE和排序( SELECTORDER 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_ciutf8_unicode_ci

对于每个排序规则,我分别对每个存储过程调用5次(对于utf8_general_ciutf8_unicode_ci 5次,对于utf8_unicode_ciutf8_unicode_ci 5次),然后计算平均值。

我的结果是:

benchmark_simple_select()

  • utf8_general_ci :9,957毫秒
  • utf8_unicode_ci :10,271毫秒

在此基准测试中,使用utf8_unicode_ciutf8_general_ci慢3.2%。

benchmark_select_like()

  • 使用utf8_general_ci :11,441毫秒
  • utf8_unicode_ci :12,811毫秒

在此基准测试中,使用utf8_unicode_ciutf8_general_ci慢12%。

benchmark_order_by()

  • utf8_general_ci :11,944毫秒
  • utf8_unicode_ci :12,887毫秒

在此基准测试中,使用utf8_unicode_ciutf8_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

在波兰语中,字母Ł在字母LM之前。 这种编码的好与坏都没有,这取决于您的需求。


#5楼

根据这篇文章,使用utf8mb4_general_ci代替utf8mb4_unicode_ci时,在MySQL 5.7上有相当大的性能优势: https ://www.percona.com/blog/2019/02/27/charset-and-collat​​ion-settings-impact -关于mysql-performance /

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!