1.
PostgreSQL 11 새기능 소개
김상기
이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 이용할 수 있습니다.
2.
2
1. 마이그레이션 고려 사항
1.1. pg_dump --create
데이터베이스 생성 구문은 pg_dump 명령으로 만든다.
이때 encoding, lc_collate, lc_ctype 값은 무조건 덤프된다.
1.2. 함수 이름과 같은 칼럼 이름을 함수 호출 형식으로 사용될 경우, 함수 우선
1.3. 테이블이나 도메인에 정의된 제약 조건 이름은 유일해야 한다.
기존 중복된 이름 제약 조건 찾는 쿼리
select conrelid::regclass,conname,count(*) from pg_constraint
group by conrelid,conname having count(*) > 1;
1.4. to_number('12345', '9,999') → 1234(O), 1345(X)
11 버전 이전 버전
select row_to_json(x)
from (select *, row_to_json(null) from
generate_series(1, 1)) x;
row_to_json
---------------------------------------
{"generate_series":1,"row_to_json":null}
select row_to_json(x)
from (select *, row_to_json(null) from
generate_series(1, 1)) x;
row_to_json
-------------
3.
3
1. 마이그레이션 고려 사항
1.5. xmltable, xpath 함수의 상대 경로 기준 바뀜
1.6. 시스템 카탈로그 변경 사항
1.7. 서버 환경 설정 매개 변수 변경 사항
replacement_sort_tuples 삭제 됨, jit=off 추가 됨, (외 14개 추가, 지면 관계상 생략)
11 버전 이전 버전
select xpath('r', '<d><r>a</r></d>');
xpath
-------
{}
select xpath('r', '<d><r>a</r></d>');
xpath
------------
{<r>a</r>}
삭제된 칼럼 추가된 칼럼
pg_class.relhaspkey
pg_proc.proisagg
pg_proc.proiswindow
pg_class.relrewrite
pg_proc.prokind
pg_attribute.atthasmissing
pg_index.indnkeyatts
pg_aggregate.aggfinalmodify
pg_aggregate.aggmfinalmodify
pg_partitioned_table.partdefid
pg_publication.pubtruncate
4.
4
2. 프로시져
2.1. 핵심은 코드 블럭 내 commit, rollback이 가능하다는 것
* 이전 버전
(10) postgres@postgres=# do $$
begin
loop
perform pg_sleep(1);
insert into t values (1);
commit;
end loop;
end;
$$;
오류: PL/pgSQL의 트랜잭션을 시작/종료할 수 없음
힌트: 대신 BEGIN 블록을 EXCEPTION 절과 함께 사용하십시오.
구문: PL/pgSQL 함수 "inline_code_block" 의 6번째 SQL 문
* 11 버전
(11) postgres@postgres=# do $$ …
^CCancel request sent
오류: 사용자 요청에 의해 작업을 취소합니다.
구문: SQL 구문: "SELECT pg_sleep(1)"
PL/pgSQL 함수 "inline_code_block" 의 4번째 PERFORM
(11) postgres@postgres=# select * from t;
a
---
1
1
5.
5
2. 프로시져
2.2. 함수와 프로시져 비교
(11) postgres@postgres=# create function insert_t() returns void
language plpgsql as $$
begin
loop
perform pg_sleep(1); insert into t values (1); commit;
end loop;
end;
$$;
(11) postgres@postgres=# select insert_t();
오류: 잘못된 트랜잭션 마침
구문: PL/pgSQL 함수 "insert_t()" 의 6번째 COMMIT
(11) postgres@postgres=# drop function insert_t; -- 같은 이름의 프로시져를 만들 수 없음
DROP FUNCTION
(11) postgres@postgres=# create procedure insert_t()
language plpgsql as $$
… 본문은 같은 코드
CREATE PROCEDURE
(11) postgres@postgres=# call insert_t();
^CCancel request sent
오류: 사용자 요청에 의해 작업을 취소합니다.
구문: SQL 구문: "SELECT pg_sleep(1)"
PL/pgSQL 함수 "insert_t()" 의 4번째 PERFORM
(11) postgres@postgres=# select * from t;
a
---
1
1
6.
6
2. 프로시져
2.3. 출력(INOUT 인자 모드)
●
출력은 스칼라 반환만 허용
– 테이블이나, SETOF RECORD를 반환할 방법이 없음
refcursor (참조 커서)를 반환하고, FETCH 로 풀 수는 있음
2.4. 한계 (앞으로 개선 되어야 할 부분)
●
전통적으로 함수와 프로시져 용어를 함께 썼던 개념 분리 작업
- 연산자, 트리거에서 하위 호환성 때문에, PROCEDURE 여전히 허용
●
공식 문서를 잘 읽어야 함
●
코드 내 procedure 가 정말 procedure인지 확인 해야 함
●
drop function 대신에 drop routine
●
TABLE 반환 프로시져 지원
7.
7
3. JIT 짜깁기 (Just-In Time compilation)
3.1. 개요
●
문자열로 된 쿼리를 실시간으로 바이트 코드로 바꿔(실시간 컴파일) 반복 연산
속도를 높인다. (기본 컴파일러 = llvm)
●
집계 함수, WHERE 절 뒤 조건절 연산, ORDER BY, CREATE INDEX 빨라짐
3.2. 지원 서버 만들기
●
configure --with-llvm
(그러나, CentOS 7.X 에서 그리 쉽게 만들어지지 않는다!)
llvm, cmake 패키지 설치, ᅟsrc/Makefile.global 파일 수정 필요
3.3. 환경 설정 변수
(11) postgres@postgres=# show jit<tab>
jit jit_expressions jit_provider
jit_above_cost jit_inline_above_cost jit_tuple_deforming
jit_debugging_support jit_optimize_above_cost
jit_dump_bitcode jit_profiling_support
● jit = on|off
●
jit_above_cost = 100000 : 기본값, 비용이 100000 이상일 때 jit 짜깁기 함
8.
8
3. JIT 짜깁기 compilation
3.4. 사용
(11) postgres@postgres=# SET jit=on;
(11) postgres@postgres=# EXPLAIN ANALYZE SELECT sum(a.attnum)
FROM pg_attribute a, pg_attribute b;
QUERY PLAN
------------------------------------------------------------------------------
Aggregate (cost=100933.28..100933.29 rows=1 width=8) (actual time=1151.35...
-> Nested Loop (cost=0.00..84137.12 rows=6718464 width=2) (actual time...
...
Planning Time: 0.099 ms
JIT:
Functions: 6
Options: Inlining false, Optimization false, Expressions true, Deforming true
Timing: Generation 0.645 ms, Inlining 0.000 ms, Optimization 0.284 ms,
Emission 4.632 ms, Total 5.561 ms
Execution Time: 1152.101 ms
(11) postgres@postgres=# SET jit=off;
(11) postgres@postgres=# EXPLAIN ANALYZE SELECT sum(a.attnum) ... -- 같은 쿼리
QUERY PLAN
--------------------------------------------------------------------------------
Aggregate (cost=100933.28..100933.29 rows=1 width=8) (actual time=1245.782...
-> Nested Loop (cost=0.00..84137.12 rows=6718464 width=2) (actual time=...
...
Planning Time: 0.101 ms
Execution Time: 1245.834 ms
9.
9
4. 파티션
4.1. 해시 파티션
(11) postgres@postgres=# create table users (userid varchar(20) , username varchar(40))
PARTITION BY HASH(userid);
(11) postgres@postgres=# create table users1 partition of users for values
WITH (MODULUS 3, REMAINDER 0);
(11) postgres@postgres=# create table users2 partition of users for values
WITH (MODULUS 3, REMAINDER 1);
(11) postgres@postgres=# create table users3 partition of users for values
WITH (MODULUS 3, REMAINDER 2);
(11) postgres@postgres=# d+ users
"public.users" 테이블
필드명 | 종류 | Collation | NULL허용 | 초기값 | 스토리지 | 통계수집량 | 설명
----------+-----------------------+-----------+----------+--------+----------+------------+------
userid | character varying(20) | | | | extended | |
username | character varying(40) | | | | extended | |
파티션 키: HASH (userid)
파티션들: users1 FOR VALUES WITH (modulus 3, remainder 0),
users2 FOR VALUES WITH (modulus 3, remainder 1),
users3 FOR VALUES WITH (modulus 3, remainder 2)
(11) postgres@postgres=# insert into users values ('user1','name1'),
('user2','name2'),('user3','name3');
(11) postgres@postgres=# select tableoid::regclass, * from users;
tableoid | userid | username
----------+--------+----------
users2 | user2 | name2
users3 | user1 | name1
users3 | user3 | name3
(3개 행)
10.
10
4. 파티션
4.2. DEFAULT 하위 테이블
●
목록이나, 범위 파티션에서 기타 자료 보관용.
●
VALUES 대신에 DEFAULT
create table … partition of … DEFAULT
4.3. 파티션 키 UPDATE 명령
(11) postgres@postgres=# update users set userid = 'user4'
where userid = 'user2';
(11) postgres@postgres=# select tableoid::regclass, * from users;
tableoid | userid | username
----------+--------+----------
users3 | user1 | name1
users3 | user4 | name2
users3 | user3 | name3
(3개 행)
4.4. 제약 조건과 인덱스
●
이제 상위 테이블에서 지정하면 하위 테이블 만들 때 자동으로 만든다.
●
alter table attach 에서도 자동으로 만든다.
●
자동으로 만들어진 하위 테이블의 제약 조건과 인덱스는 개별 삭제 할 수 없다.
11.
11
5. 병렬 쿼리
●
인덱스 만들 때, CREATE TABLE AS SELECT, SELECT INTO, 구체화한 뷰(mview)
만들 때.
●
hash join 에서.
●
union all 에서.
6. CREATE INDEX … INCLUDE
(11) postgres@postgres=# d addrcode
"public.addrcode" 테이블
필드명 | 종류 | Collation | NULL허용 | 초기값
--------+------+-----------+----------+--------
addrid | text | | not null |
aname | text | | |
upid | text | | |
인덱스들:
"addrcode_pkey" PRIMARY KEY, btree (addrid)
(11) postgres@postgres=# create index addrcode_upid_i on addrcode (upid)
INCLUDE (addrid, aname);
(11) postgres@postgres=# explain select addrid,aname from addrcode where upid = '3200';
QUERY PLAN
----------------------------------------------------------------------------------------
Index Only Scan using addrcode_upid_i on addrcode (cost=0.28..14.50 rows=14 width=26)
Index Cond: (upid = '3200'::text)
Los recortes son una forma práctica de recopilar diapositivas importantes para volver a ellas más tarde. Ahora puedes personalizar el nombre de un tablero de recortes para guardar tus recortes.
Crear un tablero de recortes
Compartir esta SlideShare
¿Odia los anuncios?
Consiga SlideShare sin anuncios
Acceda a millones de presentaciones, documentos, libros electrónicos, audiolibros, revistas y mucho más. Todos ellos sin anuncios.
Oferta especial para lectores de SlideShare
Solo para ti: Prueba exclusiva de 60 días con acceso a la mayor biblioteca digital del mundo.
La familia SlideShare crece. Disfruta de acceso a millones de libros electrónicos, audiolibros, revistas y mucho más de Scribd.
Parece que tiene un bloqueador de anuncios ejecutándose. Poniendo SlideShare en la lista blanca de su bloqueador de anuncios, está apoyando a nuestra comunidad de creadores de contenidos.
¿Odia los anuncios?
Hemos actualizado nuestra política de privacidad.
Hemos actualizado su política de privacidad para cumplir con las cambiantes normativas de privacidad internacionales y para ofrecerle información sobre las limitadas formas en las que utilizamos sus datos.
Puede leer los detalles a continuación. Al aceptar, usted acepta la política de privacidad actualizada.