utf8_general_ci和utf8_unicode_ci有什麼區別

utf8_general_ciutf8_unicode_ci ,在性能方面是否存在差別? php


#1樓

我想知道utf8_general_ciutf8_unicode_ci之間的性能差別是什麼,可是我沒有在互聯網上找到任何基準,所以我決定本身建立基準。 html

我建立了一個具備500,000行的很是簡單的表: mysql

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

而後,我建立了如下存儲過程來對簡單的SELECTSELECTLIKE和排序( SELECTORDER BY )進行基準測試: sql

CREATE PROCEDURE 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_ciutf8_unicode_ciless

對於每一個排序規則,我分別對每一個存儲過程調用5次(對於utf8_general_ciutf8_unicode_ci 5次,對於utf8_unicode_ciutf8_unicode_ci 5次),而後計算平均值。 dom

個人結果是: oop

benchmark_simple_select() 性能

  • utf8_general_ci :9,957毫秒
  • utf8_unicode_ci :10,271毫秒

在此基準測試中,使用utf8_unicode_ciutf8_general_ci慢3.2%。 測試

benchmark_select_like()

  • 使用utf8_general_ci :11,441毫秒
  • utf8_unicode_ci :12,811毫秒

在此基準測試中,使用utf8_unicode_ciutf8_general_ci慢12%。

benchmark_order_by()

  • utf8_general_ci :11,944毫秒
  • utf8_unicode_ci :12,887毫秒

在此基準測試中,使用utf8_unicode_ciutf8_general_ci慢7.9%。


#2樓

這篇文章很好地描述了它。

簡而言之:utf8_unicode_ci使用Unicode標準中定義的Unicode排序算法,而utf8_general_ci是更簡單的排序順序,致使「不太準確」的排序結果。


#3樓

簡而言之:

若是您須要更好的排序順序,請使用utf8_unicode_ci (這是首選方法),

但若是您對性能徹底感興趣,請使用utf8_general_ci ,但要知道它有點過期了。

在性能方面的差別很小。


#4樓

一些細節(PL)

正如咱們在這裏能夠讀到的( Peter Gulutzan ),對波蘭字母「Ł」進行排序/比較(帶筆觸的L-html esc: Ł )(小寫:「ł」-html esc: ł )有所不一樣-咱們有如下假設:

utf8_polish_ci      Ł greater than L and less than M
utf8_unicode_ci     Ł greater than L and less than M
utf8_unicode_520_ci Ł equal to L
utf8_general_ci     Ł greater than Z

在波蘭語中,字母Ł在字母LM以前。 這種編碼的好與壞都沒有,這取決於您的需求。


#5樓

根據這篇文章,使用utf8mb4_general_ci代替utf8mb4_unicode_ci時,在MySQL 5.7上有至關大的性能優點: https ://www.percona.com/blog/2019/02/27/charset-and-collat​​ion-settings-impact -關於mysql-performance /

相關文章
相關標籤/搜索