>  기사  >  데이터 베이스  >  MYSQL 신비한 HANDLER 명령 및 구현 방법_MySQL

MYSQL 신비한 HANDLER 명령 및 구현 방법_MySQL

WBOY
WBOY원래의
2016-08-20 08:48:09971검색

MySQL에는 "고대부터" 신비한 HANDLER 명령이 있었는데, 이 명령은 표준 SQL 구문이 아니므로 SQL 문에 대한 옵티마이저의 구문 분석 및 최적화 오버헤드를 줄여 쿼리 성능을 향상시킬 수 있습니다. 이것을 보면 일부 친구들은 침착하지 못할 수도 있습니다. 왜 그런 좋은 일이 널리 사용되지 않습니까? 몇 년 전에 큰 인기를 끌었던 handlersocket 플러그인과 비슷하지 않나요?

그럼 먼저 핸들러 구문 설명을 살펴보겠습니다.

HANDLER tbl_name OPEN [[AS] 별칭]
HANDLER tbl_name READ index_name { = | = > } (값1, 값2,…) [ WHERE where_condition ]
HANDLER tbl_name READ index_name { FIRST | NEXT | LAST } [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ { FIRST | NEXT } [ WHERE where_condition ] [LIMIT … ]
핸들러 tbl_name CLOSE

우선 구문 측면에서 HANDLER는 지정된 인덱스를 통해 데이터에 접근할 수 있습니다. 하지만 이 구문은 DML 작업을 지원하지 않습니다. 또한, SQL 구문 분석 감소로 인해 Handler 명령의 성능이 정말 좋습니다. Inside의 간단한 기본 키 테스트에 따르면 Handler 명령은 SQL보다 40%~45% 빠릅니다. 테스트 스크립트는 다음과 같습니다.

SET @id=FLOOR(RAND()*1000000);
HANDLER sbtest.sbtest1 OPEN AS c;
HANDLER C READ `PRIMARY` = (@id);
HANDLER C CLOSE;

Inside의 24C 테스트 서버에서 64스레드 기본 키 쿼리는 거의 37W QPS로 실행되었으며 이는 여전히 매우 인상적입니다. SQL SELECT 쿼리를 비교하면 전체적인 테스트 결과는 아래와 같습니다.

HANDLER 명령의 주요 구현은 소스 코드 sql_handler.h, sql_handler.cc에 있으며 중단점을 설정하여 특정 프로세스를 관찰할 수 있습니다. MySQL 상위 계층과 InnoDB 스토리지 엔진 계층의 주요 기능 입구는 다음과 같습니다.

코드는 다음과 같습니다.


Sql_cmd_handler_open::실행
Sql_cmd_handler_read::실행
Sql_cmd_handler_close::실행
ha_innobase::init_table_handle_for_HANDLER
ha_partition::init_table_handle_for_HANDLER() (버전 7은 HANDLER 작업 파티션 테이블을 지원합니다)

성능이 좋으니 프로덕션 환경에서 HANDLER 명령을 사용하는 모습을 보시면 어떨까요? 주로 HANDLER 명령에 다음과 같은 주요 문제가 있기 때문입니다.

일관되지 않은 읽기? ? ?
특정 열이 아닌 클러스터형 인덱스(보조 인덱스 액세스 포함)의 모든 열을 반환합니다
보조 인덱스는 LIMIT 키워드를 사용하지 않으며 1행의 레코드만 반환할 수 있습니다
HANDLER 명령어를 아는 학생들은 HANDLER 읽기에 Dirty Read 문제가 있다고 생각할 수도 있습니다. 공식 MySQL 문서에는 HANDLER 읽기에 대해 다음과 같이 나와 있습니다.

핸들러 인터페이스는 데이터의 일관된 모양을 제공할 필요가 없으므로(예: 더티 읽기 허용) 스토리지 엔진은 SELECT가 일반적으로 허용하지 않는 최적화를 사용할 수 있습니다.
그러나 MySQL 문서에는 일관성 없는 읽기가 허용된다는 내용이 정확하게 명시되어 있다는 점에 유의하는 것이 중요합니다. 그러나 InnoDB 스토리지 엔진의 HANDLER 구현은 일관된 읽기를 지원합니다. Insider의 개인 테스트에 따르면 실제로 더티 읽기 문제는 없습니다. 물론 소스 코드는 init_table_handle_for_HANDLER 함수에 READVIEW가 할당되어 있음을 알 수 있으며 주석에서도 이를 설명합니다.

/* HANDLER가 항상 일관된 읽기로 읽기를 수행하도록 합니다.
trx 격리 수준이 SERIALIZABLE로 지정된 경우 */
m_prebuild->select_lock_type = LOCK_NONE;
m_prebuild->stored_select_lock_type = LOCK_NONE;

HANDLER 명령을 사용하여 기본 키를 쿼리하는 것이 SQL 파서의 오버헤드를 줄이고 성능을 크게 향상시키는 것이 좋은 것 같습니다. 하지만 이를 위해서는 애플리케이션에 큰 변화가 필요하며, SQL의 가장 큰 장점은 표준화입니다. 저는 이것이 현재 NoSQL 데이터베이스가 겪고 있는 가장 큰 문제이기도 하다고 생각합니다. 예를 들어 MongoDB의 경우 Insider는 쿼리를 작성할 때마다 공식 명령 비교표를 열어야 합니다...

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.