web-dev-qa-db-ja.com

utf8_unicode_ciとutf8_general_ciの影響を測定するためのMySQLパフォーマンスベンチマークはありますか?

here および there を読みましたが、utf8_unicode_ci照合順序を使用すると、Unicodeテキストの処理が向上します(たとえば、「–」などの文字を展開する方法がわかっています。デフォルトのutf8_general_ciと比較して、検索と順序付けのために「oe」に変換します。これは基本的に発音区別符号を削除するだけです。残念ながら、両方の情報源は、utf8_unicode_ciutf8_general_ciよりもわずかに遅いことを示しています。

だから私の質問は:「少し遅い」とはどういう意味ですか?誰かがベンチマークを実行しましたか? -0.01%のパフォーマンスへの影響、または-25%のようなものについて話しているのでしょうか。

ご協力いただきありがとうございます。

13
MiniQuark

さて、インターネットでベンチマークが見つからなかったので、自分でベンチマークを作ることにしました。

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回(utf8_general_ciで5回、utf8_unicode_ciで5回)呼び出してから、平均値を計算しました。

結果は次のとおりです:

utf8_general_ciを使用したbenchmark_simple_select():9957ミリ秒
benchmark_simple_select()with utf8_unicode_ci:10271 ms
このベンチマークでは、utf8_unicode_ciを使用すると、utf8_general_ciよりも3.2%遅くなります。

utf8_general_ciを使用したbenchmark_select_like():11441ミリ秒
benchmark_select_like()with utf8_unicode_ci:12811 ms
このベンチマークでは、utf8_unicode_ciを使用するとutf8_general_ciよりも12%遅くなります。

utf8_general_ciを使用したbenchmark_order_by():11944ミリ秒
benchmark_order_by()with utf8_unicode_ci:12887 ms
このベンチマークでは、utf8_unicode_ciを使用すると、utf8_general_ciよりも7.9%遅くなります。

8
nightcoder

ベンチマークは表示されませんでしたが、 [〜#〜]ベンチマーク[〜#〜] 関数を使用して独自のベンチマークを実行できます。

ベンチマーク(カウント、expr)

Matthewのアドバイスに従って、MYSQLの並列インストールを実行できますが、異なるアーキテクチャ(sparc、intel、32ビット、64ビットなど)の間には大きな違いがある可能性があることを考慮してください。

2
tmow