문제

사이 utf8_general_ci 그리고 utf8_unicode_ci, 성능 측면에서 차이가 있습니까?

도움이 되었습니까?

해결책

이 두 콜라이트는 모두 UTF-8 캐릭터 인코딩을위한 것입니다. 차이점은 텍스트를 정렬하고 비교하는 방식에 있습니다.

참고 : MySQL 5.5.3이므로 사용해야합니다 utf8mb4 보다는 utf8. 둘 다 UTF-8 인코딩을 언급하지만 나이가 utf8 0xFFFD 이상의 문자의 사용을 방지하는 MySQL 특정 제한이있었습니다.

주요 차이점

  • utf8mb4_unicode_ci 범용 분류 및 비교에 대한 공식 유니 코드 규칙을 기반으로하며, 이는 광범위한 언어로 정확하게 분류됩니다.

  • utf8mb4_general_ci 속도를 향상시키기 위해 설계된 많은 단축 장치를 복용하면서 할 수있는 것만 큼 할 수있는 것만 큼 단순화 된 분류 규칙 세트입니다. 유니 코드 규칙을 따르지 않으며 특정 언어 나 문자를 사용할 때와 같은 일부 상황에서 바람직하지 않은 정렬 또는 비교를 초래합니다.

    최신 서버에서는이 성능 향상은 무시할 수 있습니다. 서버가 오늘날의 컴퓨터의 CPU 성능의 일부를 가졌을 때 고안되었습니다.

참고 : 이제 업데이트 된 버전이 있습니다 utf8mb4_unicode_ci ~라고 불리는 utf8mb4_0900_ai_ci - 이것은 유니 코드 버전 9.0의 변경 사항을 기반으로하며 분명히 더 빠릅니다. 그것은 새로운 명명 체계를 채택합니다 0900 유니 코드 버전입니다 ai 이전과 마찬가지로 악센트 불신을 의미합니다 utf8mb4_unicode_ci, 문자의 악센트는 중요하지 않습니다.

의 이점 utf8mb4_unicode_ci ~ 위에 utf8mb4_general_ci

utf8mb4_unicode_ci, 정렬 및 비교를 위해 유니 코드 규칙을 사용하는 것은 광범위한 언어의 올바른 정렬과 광범위한 특수 문자를 사용할 때 상당히 복잡한 알고리즘을 사용합니다. 이 규칙은 언어 별 규칙을 고려해야합니다. 모든 사람이 우리가 '알파벳 순서'라고 부르는 것에서 자신의 캐릭터를 분류하는 것은 아닙니다.

라틴어 (예 : "유럽") 언어가 진행되는 한, 유니 코드 분류와 단순화 사이에는 큰 차이가 없습니다. utf8mb4_general_ci MySQL에서 정렬하지만 여전히 몇 가지 차이점이 있습니다.

  • 예를 들어, 유니 코드 콜레이션은 "ss"와 같은 "ß"와 "–" "Oe"와 같은 캐릭터를 사용하는 사람들과 같은 "–"– "와 같은"– "와 같은"– "’을 정렬하는 반면 utf8mb4_general_ci 그것들을 단일 문자로 정렬합니다 (아마도 "S"와 "E"와 같은 각각).

  • 일부 유니 코드 문자는 무지한 것으로 정의됩니다. 즉, 정렬 순서에 포함해서는 안되며 비교는 다음 문자로 이동해야합니다. utf8mb4_unicode_ci 이것을 올바르게 처리합니다.

아시아 언어 나 알파벳이 다른 언어와 같은 라틴어가 아닌 언어에서는 많이있을 수 있습니다. 유니 코드 분류와 단순화의 차이 utf8mb4_general_ci 정렬. 적합성 utf8mb4_general_ci 사용 된 언어에 크게 의존합니다. 일부 언어의 경우 상당히 부적절 할 것입니다.

무엇을 사용해야합니까?

사용할 이유가 거의 없습니다 utf8mb4_general_ci 더 이상, 우리는 CPU 속도가 낮은 지점을 남겨 두었 기 때문에 성능 차이가 중요 할 정도로 충분합니다. 귀하의 데이터베이스는 이것보다 다른 병목 현상에 의해 거의 확실하게 제한됩니다.

과거에는 일부 사람들이 사용하는 것이 좋습니다 utf8mb4_general_ci 정확한 분류가 성능 비용을 정당화하기에 충분히 중요 할 때를 제외하고. 오늘날 그 성과 비용은 사라졌으며 개발자들은 국제화를 더욱 심각하게 취급하고 있습니다.

속도가 정확도보다 당신에게 더 중요하다면, 당신은 어떤 정렬도 전혀 할 수 없다는 주장이 있습니다. 정확하지 않도록 알고리즘을 더 빨리 만드는 것은 사소한 일입니다. 그래서, utf8mb4_general_ci 속도의 이유로 필요하지 않은 타협입니다. 아마도 정확성 이유에도 적합하지 않을 것입니다.

추가로 추가 할 또 다른 점은 응용 프로그램이 영어 만 지원한다는 것을 알고 있더라도 여전히 사람의 이름을 다루어야 할 수도 있습니다. 여기에는 종종 다른 언어로 사용되는 문자가 포함될 수 있습니다. . 모든 것에 유니 코드 규칙을 사용하면 매우 똑똑한 유니 코드 사람들이 정렬 작업을 제대로 만들기 위해 열심히 노력했다는 마음의 평화를 더할 수 있습니다.

부품의 의미

먼저, ci 입니다 사례에 민감합니다 정렬 및 비교. 이것은 텍스트 데이터에 적합하며 사례가 중요하지 않다는 것을 의미합니다. 다른 유형의 협업은 다음과 같습니다 cs (사례에 민감성) 사례가 중요한 텍스트 데이터의 경우 bin, 인코딩이 일치 해야하는 경우, 비트는 비트에 대해, 이는 실제로 이진 데이터를 인코딩하는 필드에 적합합니다 (예 : Base64 포함). 사례에 민감한 분류는 이상한 결과로 이어지고 사례에 민감한 비교는 문자 케이스에서만 다른 중복 값을 초래할 수 있으므로, 사례에 민감한 콜레이션은 텍스트 데이터에 대해 유리하지 않습니다. 그리고 아마도 아마도 중요 할 것이며, 바이너리 콜레이션이 더 적절할 수 있습니다.

다음, unicode 또는 general 특정 분류 및 비교 규칙, 특히 텍스트가 정규화되거나 비교되는 방식을 나타냅니다. UTF8MB4 문자 인코딩에 대한 여러 가지 규칙 세트가 있습니다. unicode 그리고 general 하나의 특정 언어가 아닌 모든 가능한 언어에서 잘 작동하려는 두 가지. 이 두 규칙 세트의 차이점은이 답변의 주제입니다. 최신 규칙 세트에는 포함됩니다 0900 유니 코드 9.0을 참조하고 unicode_520 유니 코드 5.2 참조.

그리고 마지막으로, utf8mb4 물론 내부적으로 사용되는 캐릭터 인코딩입니다. 이 답변에서 나는 유니 코드 기반 인코딩에 대해서만 이야기하고 있습니다.

다른 팁

사용 사이의 성능 차이가 무엇인지 알고 싶었습니다. utf8_general_ci 그리고 utf8_unicode_ci, 그러나 인터넷에 나열된 벤치 마크를 찾지 못했기 때문에 벤치 마크를 직접 만들기로 결정했습니다.

50 만 행으로 매우 간단한 테이블을 만들었습니다.

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

그런 다음 Simple을 벤치마킹하기 위해 다음 저장 절차를 만들었습니다. SELECT, SELECT ~와 함께 LIKE, 및 정렬 (SELECT ~와 함께 ORDER BY):

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 Collation이 사용되지만 물론 테스트 중에는 두 가지를 모두 사용했습니다. utf8_general_ci 그리고 utf8_unicode_ci.

각 정제에 대해 각 저장 절차를 5 번 전화했습니다 (5 회 utf8_general_ci 그리고 5 번 utf8_unicode_ci) 그런 다음 평균 값을 계산했습니다.

내 결과는 다음과 같습니다.

benchmark_simple_select()

  • ~와 함께 utf8_general_ci: 9,957ms
  • ~와 함께 utf8_unicode_ci: 10,271 ms

이 벤치 마크에서 utf8_unicode_ci 보다 느립니다 utf8_general_ci 3.2%.

benchmark_select_like()

  • ~와 함께 utf8_general_ci: 11,441ms
  • ~와 함께 utf8_unicode_ci: 12,811ms

이 벤치 마크에서 utf8_unicode_ci 보다 느립니다 utf8_general_ci 12%.

benchmark_order_by()

  • ~와 함께 utf8_general_ci: 11,944 ms
  • ~와 함께 utf8_unicode_ci: 12,887ms

이 벤치 마크에서 utf8_unicode_ci 보다 느립니다 utf8_general_ci 7.9%

이 게시물 그것을 아주 멋지게 묘사합니다.

요컨대 : UTF8_UNICODE_CI는 유니 코드 표준에 정의 된 UNICODE COLLATION 알고리즘을 사용하는 반면 UTF8_General_Ci는 "정확한"분류 결과를 초래하는보다 간단한 정렬 순서입니다.

MySQL 매뉴얼을 참조하십시오. 유니 코드 문자 세트 부분:

모든 유니 코드 문자 세트의 경우 _general_ci Collation을 사용하여 수행 된 작업은 _unicode_ci Collation의 작업보다 빠릅니다. 예를 들어 UTF8_General_Ci Collation에 대한 비교는 UTF8_unicode_ci의 비교보다 더 빠르지 만 약간 덜 정확합니다. 그 이유는 utf8_unicode_ci가 확장과 같은 매핑을 지원하기 때문입니다. 즉, 한 캐릭터가 다른 문자의 조합과 동일하게 비교할 때입니다. 예를 들어, 독일어와 다른 언어 "ß"는 "SS"와 같습니다. UTF8_UNICODE_CI는 또한 수축과 무시할 수있는 문자를 지원합니다. UTF8_GENERAL_CI는 확장, 수축 또는 무시할 수있는 캐릭터를 지원하지 않는 레거시 콜레이션입니다. 문자간에 일대일 비교 만 만들 수 있습니다.

요약하기 위해 UTF_GENERAL_CI는 UTF_UNICODE_CI보다 작고 덜 정확한 비교 세트를 사용합니다. ~해야 한다 전체 표준을 구현하십시오. General_Ci 세트는 계산이 적기 때문에 더 빠릅니다.

간단한 말로 :

더 나은 정렬 순서가 필요한 경우 - 사용하십시오 utf8_unicode_ci (이것은 선호되는 방법입니다),

그러나 성능에 완전히 관심이 있다면 사용하십시오 utf8_general_ci, 그러나 조금 구식이라는 것을 알고 있습니다.

성능 측면의 차이는 매우 적습니다.

일부 세부 사항 (PL)

우리가 읽을 수 있듯이 여기 (피터 굴 루 잔) 폴란드어 문자 "w"(l 뇌졸중 -Html esc와 함께 L을 분류/비교하는 데 차이가 있습니다. Ł) (소문자 : "ł"-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

폴란드어 언어 편지로 Ł 편지 후입니다 L 그리고 전에 M. 이 코딩 중 어느 것도 더 좋거나 나쁘지 않습니다. 그것은 당신의 요구에 달려 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top