기능 성능


46

저장 프로 시저 성능 (이전 기사)유용성 이 의심스러운 MySQL 배경에서 회사의 새 제품에 대한 PostgreSQL을 평가하고 있습니다.

내가하고 싶은 일 중 하나는 일부 응용 프로그램 논리 를 저장 프로 시저로 옮기는 것이므로 PostgreSQL (9.0)의 함수 사용에 대한 DO 및 DO N'T (모범 사례), 특히 성능 함정과 관련하여 요청합니다.


성능과 관련이 없는 내용에 대한 답변을 원하지 않습니까?
잭 더글러스

크리스 트래버스가 저장 프로 시저를 사용의 장점에 대해 많은 블로그, 예를 들어 여기 : ledgersmbdev.blogspot.de/2012/07/... 여기 : ledgersmbdev.blogspot.de/2012/07/...는 단지 자신의 블로그를 통해 탈지,이된다 이 주제에 관한 많은 흥미로운 기사.
a_horse_with_no_name

답변:


51

엄밀히 말하면, "저장 프로 시저"라는 용어 는 Postgres 11에 도입 된 Postgres의 SQL 프로 시저 를 가리 킵니다 .

거의 동일하지는 않지만 기능 이 있으며 처음부터 기능이 있습니다.

기능 과는 LANGUAGE sql기본적으로 (항상 내에서 실행하기 때문에 원자, 일반 SQL의 함수 래퍼 명령을 단지 배치 파일입니다 단일 거래) 받아들이는 매개 변수를 설정합니다. SQL 함수의 모든 명령문은 한 번 에 계획 되며 이는 하나의 명령문을 차례로 실행하는 것과 미묘하게 다르며 잠금이 수행되는 순서에 영향을 줄 수 있습니다.

무엇보다 가장 성숙한 언어는 PL / pgSQL ( LANGUAGE plpgsql)입니다. 잘 작동하고 지난 10 년 동안 모든 릴리스에서 개선되었지만 SQL 명령의 풀 역할을하는 것이 가장 좋습니다. SQL 계산 이외의 많은 계산을위한 것은 아닙니다.

PL / pgSQL 함수는 준비된 명령문 과 같은 쿼리를 실행합니다 . 캐시 된 쿼리 계획을 다시 사용하면 일부 계획 오버 헤드가 줄어들고 동등한 SQL 문보다 약간 빠르므로 상황에 따라 눈에 띄는 영향을 줄 수 있습니다. 이 관련 질문과 같은 부작용이있을 수도 있습니다.

이것은 매뉴얼에서 논의 된 것처럼 준비된 진술의 장단점을 가지고 있습니다 . 불규칙한 데이터 분배 및 다양한 매개 변수가있는 테이블에 대한 쿼리의 경우 지정된 매개 변수에 대해 최적화 된 실행 계획의 이득이 재 계획 비용을 능가 할 때 동적 SQLEXECUTE더 잘 수행 될 수 있습니다.

Postgres 9.2 일반 실행 계획은 여전히 ​​세션에 대해 캐시되지만 manual을 인용하기 때문에 :

이것은 매개 변수없이 준비된 명령문에 대해 즉시 발생합니다. 그렇지 않으면 예상 비용 평균 (계획 오버 헤드 포함)이 일반 계획 비용 추정치보다 비싼 계획을 생성하는 다섯 번 이상의 실행 후에 만 ​​발생합니다.

우리는 (ab) 사용하지 않고 대부분의 시간 동안 ( 두 개의 추가 오버 헤드가 거의 없음) 두 세계를 최대한 활용합니다EXECUTE . PostgreSQL Wiki PostgreSQL 9.2의 새로운 기능에 대한 세부 정보 .

Postgres 12에는 일반 또는 사용자 정의 계획을 강제 적용하기 위한 추가 서버 변수plan_cache_mode 가 도입되었습니다 . 특별한 경우에는 조심해서 사용하십시오.

응용 프로그램에서 데이터베이스 서버로의 추가 왕복막는 서버 측 기능으로 큰 성과거둘 수 있습니다 . 서버가 한 번에 최대한 많이 실행되도록하고 잘 정의 된 결과 만 반환하도록하십시오.

복잡한 함수, 특히 테이블 함수 ( RETURNING SETOF record또는 TABLE (...))의 중첩피하십시오 . 함수는 쿼리 플래너에 대한 최적화 장벽으로 사용되는 블랙 박스입니다. 외부 쿼리의 컨텍스트가 아닌 개별적으로 최적화되어 계획이 단순 해지지 만 완벽한 계획은 아닙니다. 또한 함수의 비용 및 결과 크기를 확실하게 예측할 수 없습니다.

이 규칙 의 예외 는 간단한 SQL 함수 ( LANGUAGE sql)이며 일부 전제 조건이 충족되는 경우 "인라인" 될 수 있습니다 . 이 프레젠테이션에서 Neil Conway (고급 항목) 의 쿼리 플래너 작동 방식에 대해 자세히 알아보십시오 .

PostgreSQL에서 함수는 항상 단일 트랜잭션 내에서 자동으로 실행 됩니다 . 모든 것이 성공하거나 아무것도 아닙니다. 예외가 발생하면 모든 것이 롤백됩니다. 그러나 오류 처리가 있습니다 ...

그렇기 때문에 함수가 정확히 "저장 프로 시저"아닌 이유도 있습니다 (비록 잘못 사용되는 용어가 사용 되더라도). 일부 명령은 좋아하는 , 또는 그들이 기능에서 허용되지 않도록, 트랜잭션 블록 내에서 실행할 수 없습니다. (Postgres 11부터는 SQL 프로 시저에서도 마찬가지입니다. 나중에 추가 될 수 있습니다.)VACUUMCREATE INDEX CONCURRENTLYCREATE DATABASE

몇 년 동안 수천 개의 plpgsql 함수를 작성했습니다.


2
@nhahtdh : "자동 거래"는 기술적 용어가 아닙니다. 그것은 거의 우아한 말이 아닙니다.. 내 설명 후에 지금 말하는 내용입니다. 자율 거래가 아닙니다. "자율적"은 비슷한 단어가됩니다.
Erwin Brandstetter

4
여기에서 컴파일 된 답변과 SO는 서사시 PostGreSQL 모범 사례 핸드북이 될 수 있습니다.
다 보스

10

일부는 :

  • PG는 명령문을 인라인 할 수 있으므로 가능하면 함수 언어로 SQL을 사용하십시오.
  • PG가 불변이거나 안정적인 경우 결과를 캐시 할 수 있으므로 IMMUTABLE / STABLE / VOLATILE을 올바르게 사용하십시오.
  • 함수를 실행하는 대신 입력이 null 인 경우 PG에서 null을 반환 할 수 있으므로 STRICT를 올바르게 사용하십시오.
  • 함수 언어로 SQL을 사용할 수없는 경우 PL / V8을 고려하십시오. 내가 실행 한 일부 비과학적인 테스트에서 PL / pgSQL보다 빠릅니다.
  • 트랜잭션 외부에서 발생할 수있는 장기 실행 프로세스에 LISTEN / NOTIFY를 사용하십시오.
  • 키 기반 페이지 매김이 LIMIT 기반 페이지 매김보다 빠를 수 있으므로 함수를 사용하여 페이지 매김 구현
  • 함수를 단위 테스트하십시오.

PL / V8이 PL / pgSQL보다 빠르다는 주장이 처음입니다. 이를 지원하는 (공개 된) 수치가 있습니까?
a_horse_with_no_name

@a_horse_with_no_name 아니오, 아닙니다. 내가 말했듯이, 나는 몇 가지 비과학적인 시험을했다. 그것들은 대부분 데이터 액세스가 아닌 논리였습니다. 크리스마스에 대해 반복 가능한 테스트를 수행하고 여기에 다시 게시하려고합니다.
Neil McGuigan

@a_horse_with_no_name 여기 plpgsql 대 FizzBuzz의 plv8에 대한 더러운 빠른-N-예입니다 : blog.databasepatterns.com/2014/08/plv8-vs-plpgsql.html
닐 맥기

8

일반적으로 응용 프로그램 논리를 데이터베이스로 이동하면 데이터 속도가 빨라집니다.

SQL 언어 함수 는 컨텍스트 전환이 필요하지 않기 때문에 다른 언어를 사용하는 함수 보다 SQL 언어 함수 가 더 빠르다고 생각합니다 (100 % 확실 하지는 않습니다). 단점은 절차 적 논리가 허용되지 않는다는 것입니다.

PL / pgSQL 은 내장 언어 중 가장 성숙하고 기능이 완전하지만 성능을 위해 C를 사용할 수 있습니다 (계산 집약적 인 함수에만 이점이 있지만)


7

postgresql에서 사용자 정의 함수 (UDF)를 사용하여 매우 흥미로운 작업을 수행 할 수 있습니다. 예를 들어, 사용할 수있는 수십 가지 언어가 있습니다. 내장 된 pl / sql 및 pl / pgsql은 성능과 안정성이 뛰어나고 샌드 박스 방법을 사용하여 사용자가 너무 위험한 일을하지 않도록합니다. C로 작성된 UDF는 데이터베이스 자체와 동일한 컨텍스트에서 실행되므로 최고의 성능과 성능을 제공합니다. 그러나 작은 실수만으로도 백엔드 충돌 또는 데이터 손상과 같은 큰 문제가 발생할 수 있기 때문에 불을 가지고 노는 것과 같습니다. pl / R, pl / ruby, pl / perl 등과 같은 custom pl 언어는 데이터베이스와 앱 계층을 동일한 언어로 작성할 수있는 기능을 제공합니다. 이것은 UDF를 작성하기 위해 perl 프로그래머에게 java 또는 pl / pgsql 등을 가르 칠 필요가 없기 때문에 편리합니다.

마지막으로 pl / proxy 언어가 있습니다. 이 UDF 언어를 사용하면 확장 목적으로 수십 개 이상의 백엔드 postgresql 서버에서 애플리케이션을 실행할 수 있습니다. Skype의 좋은 사람들에 의해 개발되었으며 기본적으로 가난한 사람의 수평 확장 솔루션을 허용합니다. 놀랍도록 쓰기도 쉽습니다.

이제 성능 문제와 관련하여 이것은 회색 영역입니다. 한 사람을위한 앱을 작성하고 있습니까? 아니면 1,000? 또는 10,000,000? 앱을 빌드하고 UDF를 사용하는 방법은 확장하려는 방법에 따라 다릅니다. 수천 명의 사용자를 대상으로 작성하는 경우 가장 중요한 것은 가능한 한 DB의 부하를 줄이는 것입니다. 데이터베이스로 이동하고 다시 데이터베이스로 이동하는 데이터의 양을 줄이는 UDF는 IO로드를 줄이는 데 도움이됩니다. 그러나 CPU로드가 증가하기 시작하면 문제가 될 수 있습니다. 일반적으로 말하자면 IO로드를 줄이는 것이 최우선 순위이며 CPU에 과부하가 걸리지 않도록 UDF가 효율적이어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.