//테스트 DB 버전 정보
MariaDB [employees]> select version();
+-----------------+
| version() |
+-----------------+
| 10.1.21-MariaDB |
+-----------------+
1 row in set (0.00 sec)
7.1 성능향상 - MariaDB , MySQL Enterprise
7.1.1 스레드 풀(Thread Pool)
7.1.1.1 MySQL 서버의 전통적인 연결 및 처리방식
1(Client):1(Thread) 방식
- 단점 : 스레드가 많아질 수록 서버내 자원에 대한 병목 현상 발생
- 이를 보안하기 위해서 Concurrent Thread 수를 낮추어 컨텍스트 스위치를 줄이는 위해 도입된 방법이 Thread Pool 입니다.
7.1.1.2 MariaDB의 스레드 풀
- 5.1 버전부터 기능 구현, 10.X 이후로 계속적으로 개선되고 있음
MariaDB의 Thread Pool의 장점
- 자동 스레드 개수조절
- 스레드풀 자체 관리 비용 낮음
- 운영체제에서 지원하는 스레드 방식 구현, 아닐 경우 IO 멀티 플렉싱 방법 사용
- 스레드 최대개수 제한으로 자원사용 제한
윈도우 (네이티브 스레드 풀)
- thread_pool_size 시스템 변수 지원 안됨
- 유닉스 (직접 스레드풀) 구현
- threadpool_min_threads 시스템 변수 형식적으로만 존재
- 유저 → 커넥션 정보 → 스레드풀(여유 스레드 확인,없으면 새로 생성) → 할당 → 정상 접속 및 질의 수행
- 성능향상 : CPU 바운드 작업인 경우
- 성능저하 : 쿼리요청이 늘어나다 다시 부하가 거의 없는 경우
7.1.1.3 MariaDB 스레드 풀의 사용과 튜닝
- 우선 , Thead_handling 시스템변수 값을 one-thread-per-connection 에서 pool of threads로 변경
7.1.1.3.1 윈도우즈 스레드 풀 관련 시스템 변수 설정
- thread_pool_min_threads = 최소 스레드 개수
- thread_pool_max_threads = 최대 스레드 개수
7.1.1.3.2 유닉스 계열의 스레드 풀 관련 시스템 변수 설정
thread_pool_size = 스레드 그룹개수 , MariaDB 5.5에서만 제공 |
thread_pool_stall_limit = 스레드풀이 하나도 없을 경우 대기시간 설정변수(ms), MariaDB 5.5만 제공 |
thread_pool_max_threads = 최대 스레드 개수 |
thread_pool_idle_timeout = IDLE 상태 스레드 개수를 줄이기 위한 대기 시간,MariaDB 5.5에서만 제공 |
thread_pool_oversubscribe = 인터널 파라미터 , MariaDB 5.5에서만 제공 |
extra_port = 관리자용 별도 포트 |
extra_max_connections = 최대 몇개의 커넥션을 연결할지 정의하는 파라미터 |
- 스레드풀 상태확인(Monitoring) 파라미터
threadpool_threads 스레드풀에 있는 스레드 개수 |
threadpool_idle_threads 남아있는 스레드 개수 |
7.1.1.4 주의 사항
- 스레드풀 활성화 시 스레드 캐시 비활성화 된다.
- 스레드풀을 다 사용할 경우 error log에 ERROR발생을 주기적으로 확인해야 한다.
7.2 관리 및 진단
7.2.1 show explain for <thread=id>
- MariaDB 10.0부터 스레드의 쿼리 실행계획 확인 가능
show processlist
MariaDB [employees]> show processlist;
+----+------+--------------------+-----------+---------+------+-------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+------+--------------------+-----------+---------+------+-------+------------------+----------+
| 13 | root | 192.168.56.1:49182 | employees | Sleep | 0 | | NULL | 0.000 |
| 14 | root | localhost | employees | Query | 0 | init | show processlist | 0.000 |
+----+------+--------------------+-----------+---------+------+-------+------------------+----------+
2 rows in set (0.00 sec)
- show explain for <해당 번호>; explain 명령 실행계획은 옵티마이저가 구조와 통계정보를 기반으로 예뮬레이션에 보여주는 내용이라면 show explain은 실제 수행되는 상태의 실행계획이다.
MariaDB [employees]> show processlist;
+----+------+--------------------+-----------+---------+------+--------------+----------------------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+------+--------------------+-----------+---------+------+--------------+----------------------------------+----------+
| 13 | root | 192.168.56.1:49182 | employees | Query | 3 | Sending data | select * from employees,salaries | 0.000 |
| 14 | root | localhost | employees | Query | 0 | init | show processlist | 0.000 |
+----+------+--------------------+-----------+---------+------+--------------+----------------------------------+----------+
2 rows in set (0.00 sec)
MariaDB [employees]> show explain for 13;
+------+-------------+-----------+------+---------------+------+---------+------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+------+---------------+------+---------+------+---------+-------+
| 1 | SIMPLE | employees | ALL | NULL | NULL | NULL | NULL | 299113 | |
| 1 | SIMPLE | salaries | ALL | NULL | NULL | NULL | NULL | 2837904 | |
+------+-------------+-----------+------+---------------+------+---------+------+---------+-------+
2 rows in set, 1 warning (0.03 sec)
MariaDB [employees]> show explain for 13;
ERROR 1933 (HY000): Target is not running an EXPLAINable command
7.2.2 슬로우 쿼리 로그에 실행계획 출력
- MariaDB 10.0.5 버전부터 슬로우쿼리 실행시간 + 실행계획 출력가능
log_slow_verbosity 시스템 변수 옵션 |
microtime : 각종정보를 마이크로 초 단위 표시 |
query_plan : SELECT 쿼리 실행계획 간략화 표시 |
full : 모든 옵션을 표시함 |
explain : 10.0.5 부터 추가된 옵션 , explain 결과 모두 기록하게 함 |
7.2.3 구조화된 실행 계획 출력
MariaDB [employees]> explain format=JSON
-> select count(*) from employees e,dept_emp de where de.emp_no=e.emp_no and e.last_name like '%M%';
----------------------------------------------------------------------+
| EXPLAIN |
----------------------------------------------------------------------+
| {
"query_block": {
"select_id": 1,
"table": {
"table_name": "e",
"access_type": "ALL",
"possible_keys": ["PRIMARY"],
"rows": 299113,
"filtered": 100,
"attached_condition": "(e.last_name like '%M%')"
},
"table": {
"table_name": "de",
"access_type": "ref",
"possible_keys": ["PRIMARY", "emp_no"],
"key": "PRIMARY",
"key_length": "4",
"used_key_parts": ["emp_no"],
"ref": ["employees.e.emp_no"],
"rows": 1,
"filtered": 100,
"using_index": true
}
}
} |
----------------------------------------------------------------------+
7.2.4 스레드 단위의 메모리 사용량
- MariaDB 10.0 부터 show status 명령어에 Memory_used 란 항목이 추가됨
- show global status 명령어는 전체 메모리 사용량을 의미함
MariaDB [(none)]> show status like '%Memory%';
+--------------------------+----------+
| Variable_name | Value |
+--------------------------+----------+
| Innodb_read_views_memory | 192 |
| Memory_used | 67464 |
| Qcache_free_memory | 33429488 |
+--------------------------+----------+
3 rows in set (0.00 sec)
MariaDB [(none)]> show global status like '%Memory%';
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| Innodb_read_views_memory | 192 |
| Memory_used | 207512784 |
| Qcache_free_memory | 33429488 |
+--------------------------+-----------+
3 rows in set (0.01 sec)
- 모든 스레드의 메모리 사용량을 확인하고 싶다면 INFORMATION_SCHEMA 데이터베이스로 접속해서 processlist 테이블 조회하면 된다.
MariaDB [(none)]> use information_schema
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [information_schema]> select id,user,host,memory_used from processlist;
+----+------+--------------------+-------------+
| id | user | host | memory_used |
+----+------+--------------------+-------------+
| 16 | root | localhost | 84584 |
| 15 | root | 192.168.56.1:49183 | 67464 |
+----+------+--------------------+-------------+
2 rows in set (0.00 sec)
MariaDB [information_schema]> select sum(memory_used) from processlist;
+------------------+
| sum(memory_used) |
+------------------+
| 152048 |
+------------------+
1 row in set (0.00 sec)
7.2.5 SHUTDOWN 명령어
- MariaDB 10.0.4 부터는 원격지에서 shutdown 명령어 사용 가능
7.2.6 사용자나 쿼리 실행 강제 종료(KILL)
MariaDB [information_schema]> show processlist;
+----+------+--------------------+--------------------+---------+------+-------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+------+--------------------+--------------------+---------+------+-------+------------------+----------+
| 15 | root | 192.168.56.1:49183 | employees | Sleep | 2199 | | NULL | 0.000 |
| 16 | root | localhost | information_schema | Query | 0 | init | show processlist | 0.000 |
+----+------+--------------------+--------------------+---------+------+-------+------------------+----------+
2 rows in set (0.00 sec)
MariaDB [information_schema]> kill connection 15;
Query OK, 0 rows affected (0.03 sec)
MariaDB [information_schema]> show processlist;
+----+------+-----------+--------------------+---------+------+-------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+------+-----------+--------------------+---------+------+-------+------------------+----------+
| 16 | root | localhost | information_schema | Query | 0 | init | show processlist | 0.000 |
+----+------+-----------+--------------------+---------+------+-------+------------------+----------+
1 row in set (0.00 sec)
특정 커넥션의 쿼리 강제 종료 : KILL QUERY 스레드 아이디 |
특정 커넥션의 쿼리를 쿼리 아이디로 강제 종료 : KILL QUERY ID 쿼리ID값 |
SELECT * FROM PROCESSLIST; 컬럼 QUERY_ID 조회 후 KILL QUERY ID 수행 |
(KIIL QUERY 와 KILL QUERY ID 차이 : 전자 모든 실행중인 쿼리 종료,후자 특정 쿼리만 종료) |
특정 유저의 커넥션이나 쿼리 강제 종료 : KILL CONNECTION USER '유저명' OR '유저명@%'; |
KILL QUERY USER '유저명' OR '유저명@%'; |
강제종료의 수준 조절 : KILL HARD |
SOFT QUERY 쿼리ID ; |
7.2.7 GET DIAGNOSTICS
- MySQL 5.6 and MariaDB 10.0.x 에러 발생 시 에러번호 , SQLSTATE 그리고 에러 메시지 스토어드 프로그램에서 참조할 수 있는 기능이다.
7.3 개발 생산성
7.3.1 LIMIT ROWS EXAMINED
- 레코드의 건수가 넘어서게 되면 쿼리를 중지할 수 있게 하는 기능
MariaDB [employees]> select * from employees where last_name ='Sudbeck' LIMIT ROWS EXAMINED 100;
Empty set, 1 warning (0.00 sec)
MariaDB [employees]>
MariaDB [employees]> show warnings\G
*************************** 1. row ***************************
Level: Warning
Code: 1931
Message: Query execution was interrupted. The query examined at least 101 rows, which exceeds LIMIT ROWS EXAMINED (100). The query result may be incomplete.
1 row in set (0.00 sec)
--
Message: Query execution was interrupted. The query examined at least 101 rows, which exceeds LIMIT ROWS EXAMINED (100). The query result may be incomplete.
1 row in set (0.00 sec)
MariaDB [employees]> select count(*) from dept_emp where dept_no='d001' LIMIT ROWS EXAMINED 20000;
Empty set, 1 warning (0.45 sec)
MariaDB [employees]> select count(*) from dept_emp where dept_no='d002' LIMIT ROWS EXAMINED 20000;
+----------+
| count(*) |
+----------+
| 17346 |
+----------+
1 row in set (0.14 sec)
- 위 명령어의 판정 건수는 클라이언트로 최종 전송되는 건수를 의미하는게 아니라 사용자가 요청한 결과를 만들어 내기 위해서 MariaDB서버가 내부적으로 핸들링한 레코드의 건수를 의미한다.
7.3.2 DELETE ... RETURNING ...
- 삭제된 레코드를 다시 가져오는 방법 RETURNING 절 뒤에는 집합 함수나 서브 쿼리를 사용할 수 없다.
MariaDB [employees]> insert into employees values (1, '1985-01-21','Matt','Lee','M','2014-1.18');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
MariaDB [employees]> delete from employees where first_name = 'Matt' and last_name = 'Lee' RETURNING emp_no , first_name, last_name;
+--------+------------+-----------+
| emp_no | first_name | last_name |
+--------+------------+-----------+
| 1 | Matt | Lee |
+--------+------------+-----------+
1 row in set (2.32 sec)
7.3.3 마이크로 초 단위의 시간 저장
- MariaDB 5.3 버전부터 DATETIME 타입에 0 , 3, 6 숫자를 부여하여 밀리초 , 마이크로초를 저장할 수 있다.
MariaDB [employees]> create table tb_microsecond(fd1 DATETIME(0) , fd2 DATETIME(3) , fd3 DATETIME(6));
Query OK, 0 rows affected (0.15 sec)
MariaDB [employees]> insert into tb_microsecond VALUES (NOW(6),NOW(6),NOW(6));
Query OK, 1 row affected (0.04 sec)
MariaDB [employees]> select * from tb_microsecond
-> ;
+---------------------+-------------------------+----------------------------+
| fd1 | fd2 | fd3 |
+---------------------+-------------------------+----------------------------+
| 2017-06-22 15:48:11 | 2017-06-22 15:48:11.954 | 2017-06-22 15:48:11.954716 |
+---------------------+-------------------------+----------------------------+
1 row in set (0.00 sec)
--
MariaDB [employees]> select UNIX_TIMESTAMP(now(6));
+------------------------+
| UNIX_TIMESTAMP(now(6)) |
+------------------------+
| 1498114169.195263 |
+------------------------+
1 row in set (0.00 sec)
MariaDB [employees]> select now(6),date_sub(now(6),interval 10000 MICROSECOND);
+----------------------------+---------------------------------------------+
| now(6) | date_sub(now(6),interval 10000 MICROSECOND) |
+----------------------------+---------------------------------------------+
| 2017-06-22 15:50:03.740734 | 2017-06-22 15:50:03.730734 |
+----------------------------+---------------------------------------------+
1 row in set (0.00 sec)
7.3.4 DATETIME 타입의 기본값 설정
- MySQL , MariaDB 5.5 부터는 TIMESTAMP 타입 현재시간을 기본값으로 설정가능
- DATETIME은 불가능 , MariaDB 10.0 부터 DATETIME 타입도 현재시간을 기본값으로 가질 수 있다. (CURRENT_TIMESTAMP)
MariaDB [employees]> create table tb_datetime(
-> fd1 INT PRIMARY KEY,
-> fd2 DATETIME DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.32 sec)
MariaDB [employees]> insert into tb_datetime (fd1) values (1);
Query OK, 1 row affected (0.04 sec)
MariaDB [employees]> select * from tb_datetime;
+-----+---------------------+
| fd1 | fd2 |
+-----+---------------------+
| 1 | 2017-06-22 15:51:33 |
+-----+---------------------+
1 row in set (0.00 sec)
7.3.5 정규 표현식 기능 확장
- MySQL 5.5 / 5.6 POSIX 호환 정규 표현식 라이브러리 사용
- MariaDB 10.0.5 PCRE 정규 표현식 라이브러리 사용
- REGEXP_REPLACE (문자열 , 정규표현식 , 대체문자열) - 변환
MariaDB [employees]> select regexp_replace('abc123def','[0-9]','*') as change_number;
+---------------+
| change_number |
+---------------+
| abc***def |
+---------------+
1 row in set (0.00 sec)
- REGEXP_INSTR(문자열 , 정규표현식) - 위치 리턴
MariaDB [employees]> select regexp_instr('KOREAN','N') as return_num;
+------------+
| return_num |
+------------+
| 6 |
+------------+
1 row in set (0.00 sec)
- REGEXP_SUBSTR(문자열 , 정규표현식) - 일치 문자열 가져오기
MariaDB [employees]> select regexp_substr('ABC123DEF','[A-Z]+');
+-------------------------------------+
| regexp_substr('ABC123DEF','[A-Z]+') |
+-------------------------------------+
| ABC |
+-------------------------------------+
1 row in set (0.00 sec)
7.3.6 가상(Virtual) 컬럼
- 다른 컬럼에 의해서 자동으로 설정되는 기능을 의미함.
제약사항 |
가상 컬럼의 표현식은 252자 내외 |
서브 쿼리와 같이 외부 테이블의 데이터를 참조하는 표현식은 사용 불가능 |
사용자정의 함수와 스토어드 함수 , not-determinstic 함수(내장함수)를 이용한 표현식에 사용불가 |
상수 표현식은 가상컬럼의 표현식으로 불가 |
가상컬럼의 표현식에 다른 가상컬럼은 사용 불가 |
VIRTUAL |
---|
해당 기능 지원 스토리지 엔진 : InnoDB , Aria , MyISAM , CONNECT 스토리지 인덱스 생성 불가 , SELECT 쿼리 시만 내부적 계산과정 수행 , ALTER TABLE MODIFY , CHANGE 등 수행불가 |
MariaDB [employees]> CREATE TABLE tb_virtual_emp (
-> emp_no int(11) NOT NULL,
-> birth_date date NOT NULL,
-> first_name varchar(14) NOT NULL,
-> birth_month TINYINT AS (MONTH(birth_date)) VIRTUAL,
-> PRIMARY KEY(emp_no),
-> KEY ix_firstname(first_name)
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.10 sec)
MariaDB [employees]> insert into tb_virtual_emp (emp_no,birth_date,first_name)
-> select emp_no,birth_date,first_name from employees;
Query OK, 300024 rows affected (15.56 sec)
Records: 300024 Duplicates: 0 Warnings: 0
select * from tb_virtual_emp;
...
| 15025 | 1952-12-03 | Vincent | 12 |
| 15026 | 1963-12-12 | Geoffrey | 12 |
| 15027 | 1959-04-17 | Sudhanshu | 4 |
| 15028 | 1963-07-25 | Toney | 7 |
| 15029 | 1954-04-08 | Giordano | 4 |
| 15030 | 1954-02-21 | Rasikan | 2 |
...
PERSISTENT |
MariaDB 모든 엔진에서 사용가능 , 인덱스 생성 가능 , ALTER TABLE MODIFY , CHANGE 등 사용가능 |
7.3.7 동적(Dynamic) 칼럼
- NoSQL 형태의 데이터 저장 및 접근을 위해서 동적 칼럼 기능을 제공함.
- 하나의 대용량 컬럼 정의하고, 그 칼럼을 여러 개의 임의 칼럼으로 정의하여 사용가능
동적 칼럼 함수 |
COLUMN_CREATE : 컬럼명 , 컬럼값 지정하여 생성 |
COLUMN_ADD : 기존 동적컬럼에 새로운 논리적 컬럼 추가 |
COLUMN_GET : 동적 컬럼의 논리 컬럼의 값을 가져오는 함수 |
COLUMN_DELETE : 논리 동적 컬럼 제거 |
COLUMN_EXISTS : 지정된 이름의 논리 동적 컬럼이 존재하는지 체크 |
COLUMN_LIST : 동적 컬럼이 가지고 있는 논리 동적 컬럼 목록 추출 |
COLUMN_CHECK : 오류없이 정상 패키징 되었는지 확인하는 함수 |
COLUMN_JSON : JSON 포맷으로 반환 |
MariaDB [employees]> create table tb_dynamic_emp(
-> emp_no INT NOT NULL,
-> dyna_cols BLOB,
-> PRIMARY KEY (emp_no));
Query OK, 0 rows affected (0.36 sec)
MariaDB [employees]> INSERT INTO tb_dynamic_emp(emp_no , dyna_cols) VALUES (10001,COLUMN_CREATE('birth_date','1983-05-07','first_name','Dong-Hoon','last_name','Lee','gender','M','hire_date','2011-06-01'));
Query OK, 1 row affected (0.04 sec)
MariaDB [employees]> select * from tb_dynamic_emp\G
*************************** 1. row ***************************
emp_no: 10001
dyna_cols: , # " nderhire_datelast_namebirth_datefirst_name!M!2011-06-01!Lee!1983-05-07!Dong-Hoon
1 row in set (0.00 sec)
MariaDB [employees]> update tb_dynamic_emp SET dyna_cols=COLUMN_ADD(dyna_cols,'country','Korea');
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [employees]> select emp_no,COLUMN_GET(dyna_cols,'country' as CHAR) as v_country from tb_dynamic_emp;
+--------+-----------+
| emp_no | v_country |
+--------+-----------+
| 10001 | Korea |
+--------+-----------+
1 row in set (0.00 sec)
MariaDB [employees]> update tb_dynamic_emp SET dyna_cols=COLUMN_DELETE(dyna_cols,'country');
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [employees]> select emp_no,COLUMN_EXISTS(dyna_cols,'country') as existence from tb_dynamic_emp;
+--------+-----------+
| emp_no | existence |
+--------+-----------+
| 10001 | 0 |
+--------+-----------+
1 row in set (0.00 sec)
MariaDB [employees]> select emp_no,column_list(dyna_cols) as col_list from tb_dynamic_emp;
+--------+------------------------------------------------------------+
| emp_no | col_list |
+--------+------------------------------------------------------------+
| 10001 | `gender`,`hire_date`,`last_name`,`birth_date`,`first_name` |
+--------+------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [employees]> select emp_no,COLUMN_CHECK(dyna_cols) as is_valid from tb_dynamic_emp;
+--------+----------+
| emp_no | is_valid |
+--------+----------+
| 10001 | 1 |
+--------+----------+
1 row in set (0.00 sec)
MariaDB [employees]> select emp_no,COLUMN_JSON(dyna_cols) as is_valid from tb_dynamic_emp;
+--------+--------------------------------------------------------------------------------------------------------------+
| emp_no | is_valid |
+--------+--------------------------------------------------------------------------------------------------------------+
| 10001 | {"gender":"M","hire_date":"2011-06-01","last_name":"Lee","birth_date":"1983-05-07","first_name":"Dong-Hoon"} |
+--------+--------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
h2 .7.4 파티션
7.4.1. 명시적 파티션 지정
다음 SQL문에 직접 파티션 명시 가능
SELECT
DELETE
INSERT
REPLACE
UPDATE
LOAD DATA
LOAD XML
FROM 절 뒤 테이블명 뒤에 PARTITION 절을 명시하고 해당 파티션을 입력한다.
7.4.1.1 명시적 파티션 지정 사용법
MariaDB [employees]> CREATE TABLE tb_partition_employees(
-> emp_no int NOT NULL,
-> birth_date date NOT NULL,
-> first_name varchar(14) NOT NULL,
-> last_name varchar(16) NOT NULL,
-> gender enum('M','F') NOT NULL,
-> hire_date date NOT NULL
-> ) ENGINE=InnoDB
-> PARTITION BY RANGE COLUMNS(hire_date)(
-> PARTITION p0 VALUES LESS THAN ('1990-01-01'),
-> PARTITION p1 VALUES LESS THAN ('2000-01-01'),
-> PARTITION p2 VALUES LESS THAN ('2010-01-01')
-> );
Query OK, 0 rows affected (0.49 sec)
MariaDB [employees]> Insert Into tb_partition_employees SELECT * FROM employees;
Query OK, 300024 rows affected (13.55 sec)
Records: 300024 Duplicates: 0 Warnings: 0
MariaDB [employees]> SELECT COUNT(*) from tb_partition_employees;
+----------+
| COUNT(*) |
+----------+
| 300024 |
+----------+
1 row in set (1.14 sec)
MariaDB [employees]> SELECT COUNT(*) from tb_partition_employees PARTITION(p0);
+----------+
| COUNT(*) |
+----------+
| 164797 |
+----------+
1 row in set (0.55 sec)
MariaDB [employees]> SELECT COUNT(*) from tb_partition_employees PARTITION(p1);
+----------+
| COUNT(*) |
+----------+
| 135214 |
+----------+
1 row in set (0.50 sec)
MariaDB [employees]> SELECT COUNT(*) from tb_partition_employees PARTITION(p1,p2);
+----------+
| COUNT(*) |
+----------+
| 135227 |
+----------+
1 row in set (0.31 sec)
MariaDB [employees]> insert into tb_partition_employees PARTITION(p0) values (1,'1984-01-12','Matt','Lee','M','2009-01-01');
ERROR 1748 (HY000): Found a row not matching the given partition set
MariaDB [employees]> select * from tb_partition_employees where emp_no=10001;
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date |
+--------+------------+------------+-----------+--------+------------+
| 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 |
+--------+------------+------------+-----------+--------+------------+
1 row in set (0.90 sec)
MariaDB [employees]> select * from tb_partition_employees PARTITION(p2) where emp_no=10001;
Empty set (0.00 sec)
MariaDB [employees]> update tb_partition_employees PARTITION(p2) set gender='F' where emp_no=10001;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0
MariaDB [employees]> update tb_partition_employees PARTITION(p0) set gender='F' where emp_no=10001;
Query OK, 1 row affected (0.89 sec)
Rows matched: 1 Changed: 1 Warnings: 0
7.4.1.2 명시적 파티션 지정 기능의 용도
- 명시적인 파티션 지정 기능은 옵티마이저가 파티션 프루닌ㅇ을 제대로 처리하지 못할 떄 명시적으로 사용할 파티션을 지정해 주는 용도로 사용할 수 있다.
MariaDB [employees]> create function getDate()
-> RETURNS DATE
-> NOT DETERMINISTIC --> 파티션 프루닝기능 제거역활
-> RETURN '2000-01-02';
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> explain partitions
-> select * from tb_partition_employees where hire_date=getDate()\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tb_partition_employees
partitions: p0,p1,p2
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 299356
Extra: Using where
1 row in set (0.00 sec)
MariaDB [employees]> explain partitions
-> select * from tb_partition_employees PARTITION(p2) where hire_date=getDate()\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tb_partition_employees
partitions: p2
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 13
Extra: Using where
1 row in set (0.01 sec)
7.4.2 파티션 테이블 스페이스 교체(Exchange)
MySQL 5.6 과 MariaDB 10.0 추가 기능 |
---|
Exchange 기능 제약사항 |
파티션 테이블과 스와핑할 테이블 구조가 동일 |
스와핑을 할 테이블은 임시테이블이면 안됨 |
스와핑될 테이블은 파티션 조건을 만족해야한다.(파티션 범위) |
스와핑할 두 테이블은 다른 테이블들과 참조관계가 없어야한다.(Foreign Key) |
해당 테이블에 대한 INSERT , ALTER , DROP , CREATE 권한 필요 |
MariaDB [employees]> create table tb_swap(
-> emp_no int NOT NULL,
-> birth_date date NOT NULL,
-> first_name varchar(14) NOT NULL,
-> last_name varchar(16) NOT NULL,
-> gender enum('M','F') NOT NULL,
-> hire_date date NOT NULL
-> )ENGINE=InnoDB;
Query OK, 0 rows affected (0.11 sec)
MariaDB [employees]> insert into tb_swap values(1,'1985-01-12','Matt','Lee','M','1989-10-10');
Query OK, 1 row affected (0.01 sec)
MariaDB [employees]> SELECT COUNT(*) from tb_partition_employees PARTITION(p0);
+----------+
| COUNT(*) |
+----------+
| 164797 |
+----------+
1 row in set (0.36 sec)
MariaDB [employees]> select count(*) from tb_swap;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
MariaDB [employees]> alter table tb_partition_employees EXCHANGE PARTITION p0 WITH TABLE tb_swap;
Query OK, 0 rows affected (0.14 sec)
MariaDB [employees]> SELECT COUNT(*) from tb_partition_employees PARTITION(p0);
+----------+
| COUNT(*) |
+----------+
| 1 |
+----------+
1 row in set (0.01 sec)
MariaDB [employees]> select count(*) from tb_swap;
+----------+
| count(*) |
+----------+
| 164797 |
+----------+
1 row in set (0.36 sec)
MariaDB [employees]> alter table tb_partition_employees EXCHANGE PARTITION p1 WITH TABLE tb_swap;
ERROR 1737 (HY000): Found a row that does not match the partition