mysql with - utf8_general_ci와 utf8_unicode_ci의 차이점은 무엇입니까?




encoding create (5)

utf8_general_ciutf8_unicode_ci 사이에는 성능 측면에서 차이가 있습니까?


Answers

mysql 매뉴얼 인 Unicode Character Sets 섹션을 참조하십시오 :

모든 유니 코드 문자 집합의 경우 _general_ci 데이터 정렬을 사용하여 수행 된 작업이 _unicode_ci 데이터 정렬의 작업보다 빠릅니다. 예를 들어, utf8_unicode_ci에 대한 비교보다 utf8_general_ci 데이터 정렬에 대한 비교가 빠르지 만 정확하지는 않습니다. 그 이유는 utf8_unicode_ci가 확장과 같은 매핑을 지원하기 때문입니다. 즉, 한 문자가 다른 문자의 조합과 동일한 것으로 비교 될 때. 예를 들어, 독일어와 다른 언어에서 "ß"는 "ss"와 같습니다. utf8_unicode_ci는 또한 수축과 무시할 수있는 문자를 지원합니다. utf8_general_ci는 확장, 축소 또는 무시할 수있는 문자를 지원하지 않는 기존의 데이터 정렬입니다. 문자 사이에 일대일 비교 만 할 수 있습니다.

요약하면, utf_general_ci는 전체 표준을 구현해야하는 utf_unicode_ci와 비교하여 (표준에 따라) 작고 정확하지 않은 비교 집합을 사용합니다. 수행 할 계산이 적기 때문에 general_ci 집합이 더 빠릅니다.


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

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, LIKE를 사용한 SELECT 및 정렬 (ORDER BY와 SELECT)을 벤치마킹하기 위해 다음 저장 프로 시저를 만들었습니다.

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 ms
utf8_unicode_ci가있는 benchmark_simple_select () : 10271ms
utf8_unicode_ci를 사용하는이 벤치 마크에서는 utf8_general_ci보다 3.2 % 느립니다.

utf8_general_ci로 benchmark_select_like () : 11441 MS
utf8_unicode_ci를 사용하는 benchmark_select_like () : 12811 ms
utf8_unicode_ci를 사용하는이 벤치 마크에서는 utf8_general_ci보다 12 % 느립니다.

utf8_general_ci를 사용하는 benchmark_order_by () : 11944ms
utf8_unicode_ci가있는 benchmark_order_by () : 12887ms
utf8_unicode_ci를 사용하는이 벤치 마크에서는 utf8_general_ci보다 7.9 % 느립니다.


간단히 말하면 :

더 나은 정렬 순서가 필요하다면 - utf8_unicode_ci 사용 utf8_unicode_ci (이것은 선호되는 방법입니다).

하지만 성능에 완전히 관심이 있다면 - utf8_general_ci 사용하십시오. 그러나 조금 구식임을 압니다.

성능면에서의 차이는 매우 미약합니다.


이 게시물 은 매우 잘 설명합니다.

요약하면 : utf8_unicode_ci는 유니 코드 표준에 정의 된대로 유니 코드 데이터 정렬 알고리즘을 사용하지만 utf8_general_ci는보다 단순한 정렬 순서이므로 "덜 정확한"정렬 결과가됩니다.


MySQL 에는 사용자 정의 변수 개념이 있습니다 .

그것들은 세션에서 어딘가에 초기화되고 세션이 끝날 때까지 값을 유지할 수있는 느슨하게 형식화 된 변수입니다.

앞에 @ 기호가 붙습니다. @var

이 변수는 SET 문 또는 쿼리의 내부에서 초기화 할 수 있습니다.

SET @var = 1

SELECT @var2 := 2

MySQL 에서 저장 프로 시저를 개발할 때 입력 매개 변수를 전달하고 지역 변수를 선언 할 수 있습니다.

DELIMITER //

CREATE PROCEDURE prc_test (var INT)
BEGIN
    DECLARE  var2 INT;
    SET var2 = 1;
    SELECT  var2;
END;
//

DELIMITER ;

이 변수에는 접두어가 붙지 않습니다.

프로 시저 변수와 세션 별 사용자 정의 변수의 차이점은 프로 시저가 호출 될 때마다 프로 시저 변수가 NULL 로 다시 초기화되는 반면 세션 별 변수는 다음과 같지 않습니다.

CREATE PROCEDURE prc_test ()
BEGIN
    DECLARE var2 INT DEFAULT 1;
    SET var2 = var2 + 1;
    SET @var2 = @var2 + 1;
    SELECT  var2, @var2;
END;

SET @var2 = 1;

CALL prc_test();

var2  @var2
---   ---
2     2


CALL prc_test();

var2  @var2
---   ---
2     3


CALL prc_test();

var2  @var2
---   ---
2     4

보시다시피 var2 (프로 시저 변수)는 프로 시저가 호출 될 때마다 다시 초기화되지만 @var2 (세션 특정 변수)는 초기화되지 않습니다.

(사용자 정의 변수 외에도 MySQL에는 @@global.port 와 같은 "전역 변수"또는 @@session.sql_mode 와 같은 "세션 변수"가 될 수있는 미리 정의 된 "시스템 변수"가 있으며 이러한 "세션 변수 "는 세션 별 사용자 정의 변수와 관련이 없습니다.





mysql unicode