Czy istnieje test wydajności MySQL do pomiaru wpływu utf8_unicode_ci na utf8_general_ci?

13

Czytałem tu i ówdzie, że użycie utf8_unicode_cisortowania zapewnia lepsze przetwarzanie tekstu w Unicode (na przykład, jak rozszerzyć znaki takie jak „œ” na „oe” w celu wyszukiwania i porządkowania) w porównaniu do domyślnego, utf8_general_ciktóry w zasadzie po prostu usuwa znaki diakrytyczne. Niestety oba źródła wskazują, że utf8_unicode_cijest nieco wolniejszy niż utf8_general_ci.

Moje pytanie brzmi: co oznacza „nieco wolniej”? Czy ktoś przeprowadził testy porównawcze? Czy mówimy o wpływie na wydajność wynoszącym -0,01%, czy raczej na poziomie -25%?

Dzięki za pomoc.

MiniQuark
źródło
Jeśli chodzi o punkt odniesienia, dlaczego nie skorzystać z czasu zapytania? Mogę być idiotą, ale co, jeśli uruchomiłeś maszynę wirtualną i przetestowałeś czas zapytania na dużym, skomplikowanym zapytaniu dla obu kodowań znaków? (Nie widziałem wcześniej przeprowadzania testów porównawczych)
Ablue

Odpowiedzi:

8

Cóż, nie znalazłem żadnych testów porównawczych w Internecie, więc sam postanowiłem je przeprowadzić.

Stworzyłem bardzo prostą tabelę z 500000 wierszami:

CREATE TABLE test(
  ID INT(11) DEFAULT NULL,
  Description VARCHAR(20) DEFAULT NULL
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;

Następnie wypełniłem je losowymi danymi, uruchamiając tę ​​procedurę składowaną:

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

Następnie utworzyłem następujące procedury składowane, aby porównać proste WYBIERZ, WYBIERZ JAK PODOBNY i sortuj (WYBIERZ przy 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

W powyższych procedurach przechowywanych stosuje się zestawienie utf8_general_ci, ale oczywiście podczas testów użyłem zarówno utf8_general_ci, jak i utf8_unicode_ci.

Każdą procedurę przechowywaną wywołałem 5 razy dla każdego zestawienia (5 razy dla utf8_general_ci i 5 razy dla utf8_unicode_ci), a następnie obliczyłem wartości średnie.

Oto wyniki:

benchmark_simple_select () z utf8_general_ci: 9957 ms
benchmark_simple_select () z utf8_unicode_ci: 10271 ms
W tym teście użycie utf8_unicode_ci jest wolniejsze niż utf8_general_ci o 3,2%.

benchmark_select_like () z utf8_general_ci: 11441 ms
benchmark_select_like () z utf8_unicode_ci: 12811 ms
W tym teście użycie utf8_unicode_ci jest wolniejsze niż utf8_general_ci o 12%.

benchmark_order_by () z utf8_general_ci: 11944 ms
benchmark_order_by () z utf8_unicode_ci: 12887 ms
W tym teście użycie utf8_unicode_ci jest wolniejsze niż utf8_general_ci o 7,9%.

nightcoder
źródło
2

Nie widziałem żadnego testu porównawczego, ale możesz uruchomić swój własny za pomocą funkcji BENCHMARK :

BENCHMARK (liczba, wyrażenie)

Zgodnie z zaleceniami Matthew możesz uruchomić równoległą instalację MYSQL, ale weź pod uwagę, że może istnieć ogromna różnica między różnymi architekturami (sparc, intel, 32bit, 64bit, ...).

tmow
źródło