Чи є показник продуктивності MySQL для вимірювання впливу utf8_unicode_ci проти utf8_general_ci?


13

Я тут і там читав, що використання utf8_unicode_ciзіставлення забезпечує кращу обробку тексту унікоду (наприклад, він знає, як розгорнути такі символи, як 'œ', на 'oe' для пошуку та впорядкування) порівняно з типовим, utf8_general_ciщо в основному лише знімає діакритику. На жаль, обидва джерела вказують, що utf8_unicode_ciце трохи повільніше, ніж utf8_general_ci.

Тож моє запитання: що означає «трохи повільніше»? Хтось запускав орієнтири? Ми говоримо про -0,01% вплив продуктивності чи, скоріше, про -25%?

Спасибі за вашу допомогу.


Щодо еталону, чому б не використати час запиту? Я, можливо, ідіот, але що робити, якщо ви запустили машину віртуального контролю і перевірите час запиту на великому складному запиті для обох кодувань символів? (Я раніше не бачив тестування, яке було зроблено для цього)
Аблуація

Відповіді:


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 ms
benchmark_simple_select () з utf8_unicode_ci: 10271 ms
У цьому еталоні використання utf8_unicode_ci повільніше, ніж utf8_general_ci на 3,2%.

benchmark_select_like () з utf8_general_ci: 11441 ms
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 :

БЕНЧМАРК (кол., Expr)

Як радив Метью, ви можете запустити паралельну установку MYSQL, але врахуйте, що між різною архітектурою може бути величезна різниця (sparc, intel, 32bit, 64bit, ...).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.