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

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

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

所以我的问题是:“稍微慢一点”是什么意思?有人做过基准测试吗?我们说的是 -0.01% 的性能影响,还是 -25% 之类的影响?

感谢您的帮助。

答案1

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

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

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、带有 LIKE 的 SELECT 和排序 (带有 ORDER BY 的 SELECT) 进行基准测试:

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

在上面的存储过程中使用了 utf8_general_ci 排序规则,但当然在测试期间我同时使用了 utf8_general_ci 和 utf8_unicode_ci。

我对每个排序规则调用了每个存储过程 5 次(对 utf8_general_ci 调用 5 次,对 utf8_unicode_ci 调用 5 次),然后计算平均值。

结果如下:

benchmark_simple_select() 与 utf8_general_ci: 9957 毫秒
benchmark_simple_select() 与 utf8_unicode_ci: 10271 毫秒
在此基准测试中,使用 utf8_unicode_ci 比 utf8_general_ci 慢 3.2%。

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

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

答案2

我没有看到任何基准测试,但你可以使用基准功能:

BENCHMARK(计数,表达式)

根据 Matthew 的建议,您可以运行 MYSQL 的并行安装,但请考虑不同架构(sparc、intel、32 位、64 位……)之间可能存在巨大差异。

相关内容