Существует ли тест производительности MySQL для измерения влияния utf8_unicode_ci по сравнению с utf8_general_ci?


13

Я читал здесь и там, что использование utf8_unicode_ciсопоставления обеспечивает лучшую обработку текста в Юникоде (например, он знает, как развернуть такие символы, как «œ» в «oe» для поиска и упорядочения) по сравнению со стандартным значением, utf8_general_ciкоторое в основном просто исключает диакритические знаки. К сожалению, оба источника указывают, что utf8_unicode_ciэто немного медленнее, чем utf8_general_ci.

Итак, мой вопрос: что означает «немного медленнее»? Кто-нибудь запускал тесты? Мы говорим о влиянии на производительность -0,01% или, скорее, о -25%?

Спасибо за вашу помощь.


Что касается теста, почему бы не использовать время запроса? Я могу быть идиотом, но что если вы запустили виртуальную машину и протестировали время запроса для большого сложного запроса для обеих кодировок символов? (Я не видел тестов, сделанных для этого раньше)
Ablue

Ответы:


8

Ну, я не нашел никаких тестов в Интернете, поэтому я решил сделать тесты самостоятельно.

Я создал очень простую таблицу с 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, SELECT с LIKE и сортировки (SELECT с 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

В хранимых процедурах выше используется сортировка utf8_general_ci, но, конечно, во время тестов я использовал как utf8_general_ci, так и utf8_unicode_ci.

Я вызывал каждую хранимую процедуру 5 раз для каждого сопоставления (5 раз для utf8_general_ci и 5 раз для utf8_unicode_ci), а затем вычислял средние значения.

Вот результаты:

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 мс
benchmark_select_like () с utf8_unicode_ci: 12811 мс
В этом тесте использование utf8_unicode_ci медленнее, чем utf8_general_ci на 12%.

benchmark_order_by () с utf8_general_ci: 11944 мс
benchmark_order_by () с utf8_unicode_ci: 12887 мс
В этом тесте с использованием utf8_unicode_ci происходит медленнее , чем utf8_general_ci на 7,9%.


2

Я не видел никаких тестов, но вы можете запустить свой собственный, используя функцию BENCHMARK :

ЭТАЛОН (количество, выражение)

По совету Мэтью вы можете запустить параллельную установку MYSQL, но учтите, что между различными архитектурами может быть огромное различие (sparc, intel, 32bit, 64bit, ...).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.