PostgreSQL 9.6에서 발생하는 문제를 이해하고 (아마도 향상시킬 수 있습니다.) 궁금합니다. 이름은 단순화되었지만 나머지는 모두 psql
세션에서 가져 왔습니다.쿼리에서 COUNT 동작 이해 vs. EXPLAIN 대 함수
구체화 된보기, mv
으로 시작합니다.
CREATE FUNCTION count_mv() RETURNS BIGINT AS $$
SELECT COUNT(*) FROM mv;
$$ LANGUAGE SQL STABLE PARALLEL SAFE;
및
CREATE FUNCTION mv_pks() RETURNS TABLE (table_pk INTEGER) AS $$
SELECT table_pk FROM mv;
$$ LANGUAGE SQL STABLE PARALLEL SAFE;
하자 시간 일부 쿼리 :
첫째, 나는 두 가지 간단한 기능을 만들 수 있습니다.
db=>\timing on
나는 매우 빠르게 구체화 된 뷰의 결과를 셀 수 있습니다.
db=> SELECT COUNT(*) FROM mv;
count
---------
2567883
(1 row)
Time: 79.803 ms
어떻게하는지 보자.
db=> EXPLAIN ANALYZE SELECT COUNT(*) FROM mv;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=41331.24..41331.25 rows=1 width=8) (actual time=765.681..765.681 rows=1 loops=1)
-> Gather (cost=41330.62..41331.23 rows=6 width=8) (actual time=765.557..765.670 rows=7 loops=1)
Workers Planned: 6
Workers Launched: 6
-> Partial Aggregate (cost=40330.62..40330.63 rows=1 width=8) (actual time=760.175..760.175 rows=1 loops=7)
-> Parallel Seq Scan on mv (cost=0.00..39261.09 rows=427809 width=0) (actual time=0.014..397.952 rows=366840 loops=7)
Planning time: 0.326 ms
Execution time: 769.934 ms
(8 rows)
좋습니다. 그래서 여러 명의 근로자를 이용하고 있습니다. 하지만 EXPLAIN ANALYZE
을 사용할 때 쿼리가 왜 그렇게 느린가?
STABLE
를 선언 된
count_mv()
기능을 사용합니다.
db=> select count_mv();
count_mv
------------
2567883
(1 row)
Time: 406.058 ms
와우! 왜 이것이 Materialized View에서 동일한 SQL보다 느립니다? 그리고 훨씬 더 천천히! 평행 한 노동자를 이용하지 않습니까? 그렇지 않다면 왜 안됩니까? 다음 응답에 제안한
가 편집
을 시작 I는 auto_explain
모듈을로드하고, 함수 호출에 EXPLAIN
는 로그 출력을 조사했다.
Query Text:
SELECT COUNT(*) FROM mv;
Finalize Aggregate (cost=41331.60..41331.61 rows=1 width=8) (actual time=1345.446..1345.446 rows=1 loops=1)
-> Gather (cost=41330.97..41331.58 rows=6 width=8) (actual time=1345.438..1345.440 rows=1 loops=1)
Workers Planned: 6
Workers Launched: 0
-> Partial Aggregate (cost=40330.97..40330.99 rows=1 width=8) (actual time=1345.435..1345.435 rows=1 loops=1)
-> Parallel Seq Scan on mv (cost=0.00..39261.38 rows=427838 width=0) (actual time=0.020..791.022 rows=2567883 loops=1)
새로운 질문은 6 명의 직원이 계획되지만 아무도 시작되지 않는 이유입니다. 서버가 유휴 상태이고 구성이 동일하며 쿼리가 동일합니다.
최종 편집
좋습니다. 그래서 나는이 작업을 수행 할 경우 :
직접EXPLAIN ANALYZE
를 사용하지 않고 구체화 된 뷰에 행을 계산하지만, 당신이 여기 저를 신뢰해야합니다 동일한 성능
db=> SELECT COUNT(*) FROM mv_pks();
count
---------
2567883
(1 row)
Time: 72.687 ms
:이 기능의 성능이의 상태에 따라 달라집니다 함수가 작성 될 때 구체화 된 뷰. 빠른 타이밍은 테이블이 비어있을 때 함수를 작성한 결과입니다. 테이블이 꽉 찼을 때 함수를 다시 만들면 함수를 실행하는 데 1000 밀리 초가 필요합니다!
내 질문을 요약하면 :- 은 왜 함수 외부 쿼리보다 훨씬 느린 매개 변수를 고려하지 않는
STABLE
SQL 함수 내부의 SQL 쿼리입니다. EXPLAIN ANALYZE
을 사용할 때 SQL 쿼리의 속도가 느린 이유는 무엇입니까?- 함수가 작성된시기에 따라 구체화 된보기의 행 수를 계산하는 것과 같거나 다른 방법보다 느릴 수있는 함수의 행을 계산할 때 왜 다른 결과가 나옵니 까?
미리 감사드립니다.
응답 해 주셔서 감사합니다. 1) 굉장한 모듈. 그것은 많은 것들을 위해 매우 도움이 될 것입니다. 새로운 Explain 출력에서 병렬성이 부족한 이유에 대한 의견은 있습니까? 2) 알았어요. 말이된다; 거의 10 배 놀랐습니다. 3) 예. 여러 번 시험을 보았습니다. 나는 심지어 같은 SQL을 사용하는 두 가지 기능을 가지고 있었지만, 서로 다른 생성 시간을 사용하여 하나씩 실행하고 다른 결과를 얻을 수있었습니다. 기묘한! – rg6
포인트 3)은 여전히 나에게 불분명하다. 나는 실험했지만 재현 할 수 없었다. 재현 가능한 테스트 케이스를 찾을 수 있습니까? –
1)에 대한 편집을 추가했습니다. 수상 내역 : 함수 내의 동일한 SQL이 병렬 처리 계획을 사용하지 않는 이유에 대해 언급 할 수 있습니다. 아니면 EXPLAIN 출력을 잘못 해석합니까? 3) 테스트 케이스에서 어떤 행동을보고 있습니까? 아니요, 이것을 신뢰할 수있게 재현 할 수는 없으며 그 점은 만족스럽지 않습니다. 어제는 빠른 성능으로 기능을 만들 수 없었습니다. 오늘은 느린 성능으로 하나를 만들 수 없습니다. 그러나 성능이 다른 기존 함수는 '\ df +'와 동일한 코드를 보여줍니다. – rg6