是否有 MySQL 性能基准来衡量 utf8_unicode_ci 与 utf8_general_ci 的影响?

Min*_*ark 13 mysql sql utf-8 unicode database-performance

在这里那里读到与基本上只是去除变音符号utf8_unicode_ci的默认值相比,使用排序规则可以确保更好地处理 unicode 文本(例如,它知道如何将诸如 'œ' 之类的字符扩展为 'oe' 以进行搜索和排序)utf8_general_ci。不幸的是,两个来源都表明这utf8_unicode_ciutf8_general_ci.

所以我的问题是:“稍微慢一点”是什么意思?有没有人运行基准测试?我们是在谈论 -0.01% 的性能影响还是类似 -25% 的影响?

谢谢你的帮助。

nig*_*der 8

好吧,我在互联网上没有找到任何基准,所以我决定自己做基准。

我创建了一个包含 500000 行的非常简单的表:

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)

然后我创建了以下存储过程来对简单的 SELECT、SELECT with LIKE 和排序(SELECT with ORDER BY)进行基准测试:

CREATE 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 次(utf8_general_ci 调用 5 次,utf8_unicode_ci 调用 5 次),然后计算平均值。

结果如下:

benchmark_simple_select() with utf8_general_ci: 9957 ms
benchmark_simple_select() with utf8_unicode_ci: 10271 ms
在这个基准测试中,使用 utf8_unicode_ci 比 utf8_general_ci 慢 3.2%。

benchmark_select_like() with utf8_general_ci: 11441 ms
benchmark_select_like() with utf8_unicode_ci: 12811 ms
在这个基准测试中,使用 utf8_unicode_ci 比 utf8_general_ci 慢 12%。

benchmark_order_by() with utf8_general_ci: 11944 ms
benchmark_order_by() with utf8_unicode_ci: 12887 ms
在这个基准测试中,使用 utf8_unicode_ci 比 utf8_general_ci 慢 7.9%。