utf8_general_ci和utf8_unicode_ci有什么区别

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


#1楼

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

而后,我建立了如下存储过程来对简单的SELECTSELECTLIKE和排序( SELECTORDER 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_ciutf8_unicode_ciless

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

个人结果是: oop

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 /

相关文章
相关标签/搜索