이 질문은 후속 조치로 제공되며 결과는 SQL function very slow compared to query without function wrapper입니다. 나는이 질문이 특정 문제에 대한 해결책을 요구하고 있었기 때문에 이것을 중복으로 생각하지 않는다는 것을 알아야한다. 나는 일반적으로 여기에있는 행동에 대한 더 많은 정보를 요구하고 그것을 재현 할 수있는 방법을 시연한다. (차이점을 증명하기 위해, 우리는 행동을 논의한 곳에서 받아 들여진 대답에 대해 상당히 긴 코멘트 스레드를 볼 수 있습니다. 특히 길이가 주어지면 주제를 벗어났다는 느낌이 들었습니다.)변동성이 다른 기능에 대해 계획자가 다른 결과를 얻는 이유는 무엇입니까?
나는 기능이 있습니다. 나는 거대한를 제거했습니다 psql의에서이 결과를 (얻을
EXPLAIN ANALYZE SELECT * FROM test(10);
"쿼리 계획"헤더 :
CREATE OR REPLACE FUNCTION test(INT)
RETURNS TABLE(num INT, letter TEXT)
VOLATILE
LANGUAGE SQL
AS $$
SELECT *
FROM (VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')) x
LIMIT $1
$$;
나는이 EXPLAIN
을 실행하면 다음과 같습니다 관심의 동작을 나타내는 샘플 하나입니다) :
Function Scan on test (cost=0.25..10.25 rows=1000 width=36) (actual time=0.125..0.136 rows=5 loops=1)
Total runtime: 0.179 ms
(2 rows)
행 추정에 유의하십시오. 그것은 1000 행을 견적.
하지만, 내가 STABLE
또는 IMMUTABLE
의 기능을 변경하는 경우 :
CREATE OR REPLACE FUNCTION test(INT)
RETURNS TABLE(num INT, letter TEXT)
STABLE
LANGUAGE SQL
AS $$
SELECT *
FROM (VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')) x
LIMIT $1
$$;
그런 다음 같은 EXPLAIN
나에게 다른 계획을 제공합니다
Limit (cost=0.00..0.06 rows=5 width=36) (actual time=0.010..0.050 rows=5 loops=1)
-> Values Scan on "*VALUES*" (cost=0.00..0.06 rows=5 width=36) (actual time=0.005..0.018 rows=5 loops=1)
Total runtime: 0.087 ms
(3 rows)
지금은 정확히 5 개 행을 추정, 그리고 그것을 보여줍니다 함수 내에 포함 된 질의에 대한 계획. 비용은 한 단계 높은 수준입니다. 런타임도 다운되었습니다. 쿼리가 너무 짧아서별로 중요하지 않을 수도 있습니다.
훨씬 많은 데이터를 처리하고 성능상의 차이가 큰 링크 질문에 비추어 볼 때 플래너는 실제로 다른 무언가를하고있는 것 같습니다. 기능이 VOLATILE
또는 STABLE
/IMMUTABLE
인지 여부.
여기서 계획자는 무엇을하고 있으며, 어떤 문서를 읽을 수 있습니까?
이러한 테스트는 PG 9.3에서 실행되었습니다.
*** 인라이닝 ***이 설명의 열쇠일지도 모릅니다. 'STABLE' 변형은 "인라인"될 수 있습니다 (함수에서 풀지 않은 쿼리 내에서 SQL 코드가 효과적으로 실행됩니다.) 더 이상 실행하지 않아도됩니다 –