Loading...
MySQL 9.5 Reference Manual 9.5의 10.10.3 Caching of Prepared Statements and Stored Programs의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
클라이언트가 하나의 세션 동안 여러 번 실행할 수 있는 특정 statements에 대해, server는 그 statement를 내부 구조로 변환하고, 실행 시 사용할 수 있도록 그 구조를 cache에 저장합니다. Caching을 사용하면, 세션 동안 해당 statement가 다시 필요해질 경우 재변환 오버헤드를 피할 수 있으므로 server가 더 효율적으로 동작할 수 있습니다. 변환과 caching은 다음과 같은 statements에 대해 발생합니다:
Prepared statements: SQL 레벨에서 처리되는 것들
(PREPARE statement 사용)과
바이너리 클라이언트/서버 프로토콜을 사용하여 처리되는 것들
(mysql_stmt_prepare() C API 함수 사용) 모두 포함됩니다.
max_prepared_stmt_count
시스템 변수는 server가 cache하는 statements의 총 개수를 제어합니다.
(모든 세션에 걸쳐 존재하는 prepared statements 개수의 합입니다.)
Stored programs (stored procedures 및 functions, triggers, events).
이 경우, server는 전체 program body를 변환하고 cache합니다.
stored_program_cache
시스템 변수는 server가 세션당 cache하는 stored programs의 대략적인 개수를 나타냅니다.
Server는 prepared statements와 stored programs에 대해 세션 단위로 caches를 유지합니다. 어떤 세션에 대해 cache된 statements는 다른 세션에서 접근할 수 없습니다. 세션이 끝나면, server는 그 세션에 대해 cache된 모든 statements를 폐기합니다.
Server가 cache된 내부 statement 구조를 사용할 때는, 그 구조가 오래되어 무효가 되지 않았는지 주의해야 합니다. Statement에서 사용되는 object에 대해 메타데이터 변경이 발생하면, 현재 object 정의와 내부 statement 구조에 표현된 정의 사이에 불일치가 생길 수 있습니다. 메타데이터 변경은 테이블을 생성, 삭제, 변경, 이름 변경, truncate 하는 DDL statements나, 테이블을 analyze, optimize, repair 하는 statements에 의해 발생합니다. 테이블 내용 변경(예를 들어
INSERT 또는
UPDATE 사용)은 메타데이터를 변경하지 않으며,
SELECT statements도 메타데이터를 변경하지 않습니다.
문제의 예시는 다음과 같습니다. 클라이언트가 다음 statement를 prepare한다고 가정해 보겠습니다:
1PREPARE s1 FROM 'SELECT * FROM t1';
SELECT *는 내부 구조에서 테이블의 column 목록으로 확장됩니다. ALTER TABLE로 테이블의 column 집합이 변경되면, 해당 prepared statement는 오래되어 유효하지 않게 됩니다. Server가 이 변경 사항을 다음 번에 클라이언트가 s1을 실행할 때 감지하지 못하면, prepared statement는 잘못된 결과를 반환하게 됩니다.
Prepared statement가 참조하는 테이블 또는 view에 대한 메타데이터 변경으로 인한 문제를 피하기 위해, server는 이러한 변경을 감지하고 다음에 statement가 실행될 때 자동으로 해당 statement를 reprepare합니다. 즉, server가 statement를 다시 parse하고 내부 구조를 재구축합니다. 또한 참조된 테이블이나 views가 table definition cache에서 제거되는 경우에도 reparsing이 발생합니다. 이는 cache에서 새로운 항목을 위한 공간을 마련하기 위해 암묵적으로 일어날 수 있고, 또는 FLUSH TABLES에 의해 명시적으로 발생할 수도 있습니다.
마찬가지로, stored program에서 사용되는 objects에 변경이 발생하면, server는 program 내에서 영향을 받는 statements를 다시 parse합니다.
Server는 expressions에서 사용되는 objects에 대한 메타데이터 변경도 감지합니다. 이는 DECLARE CURSOR와 같은 stored programs 전용 statements나,
IF,
CASE,
RETURN과 같은 flow-control statements에서 사용될 수 있습니다.
전체 stored program을 다시 parse하는 것을 피하기 위해, server는 필요할 때만 program 내에서 영향을 받는 statements나 expressions만 다시 parse합니다. 예시는 다음과 같습니다:
어떤 테이블 또는 view의 메타데이터가 변경된다고 가정합시다. Program 내에서 해당 테이블이나 view에 접근하는 SELECT *에 대해서는 reparsing이 발생하지만, 그 테이블이나 view에 접근하지 않는 SELECT *에 대해서는 reparsing이 발생하지 않습니다.
Statement가 영향을 받는 경우, server는 가능하다면 해당 statement를 부분적으로만 다시 parse합니다. 다음과 같은 CASE statement를 보겠습니다:
1CASE case_expr 2 WHEN when_expr1 ... 3 WHEN when_expr2 ... 4 WHEN when_expr3 ... 5 ... 6END CASE
메타데이터 변경이 오직 WHEN when_expr3에만 영향을 미친다면, 그 expression만 다시 parse됩니다. _case_expr_과 다른 WHEN expressions는 다시 parse되지 않습니다.
Reparsing은 처음 내부 형식으로 변환했을 때 사용되었던 기본 데이터베이스와 SQL 모드를 사용합니다.
Server는 최대 세 번까지 reparsing을 시도합니다. 모든 시도가 실패하면 에러가 발생합니다.
Reparsing은 자동으로 수행되지만, 일어나는 정도에 비례하여 prepared statement와 stored program의 성능을 저하시킵니다.
Prepared statements의 경우,
Com_stmt_reprepare
status 변수이 reprepare 횟수를 추적합니다.
10.10.2 The MyISAM Key Cache
10.11 Optimizing Locking Operations