6

PostgreSQL 9.0.4에서 실행해야하는 DELETE 쿼리가 있습니다. 내가 subselect 쿼리에서 524,289 행에 도달 할 때까지 성능이 좋은 것으로 나타났습니다. 예를 들어Postgres Materialize로 인해 삭제 쿼리의 성능이 저하됩니다.

는 524,288에서 사용 더 구체화보기가없는 및 ​​비용이 꽤 좋아 보인다 그러나

 
explain DELETE FROM table1 WHERE pointLevel = 0 AND userID NOT IN 
(SELECT userID FROM table2 fetch first 524288 rows only); 
               QUERY PLAN 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Delete (cost=13549.49..17840.67 rows=21 width=6) 
    -> Index Scan using jslps_userid_nopt on table1 (cost=13549.49..17840.67 rows=21 width=6) 
     Filter: ((NOT (hashed SubPlan 1)) AND (pointlevel = 0)) 
     SubPlan 1 
      -> Limit (cost=0.00..12238.77 rows=524288 width=8) 
       -> Seq Scan on table2 (cost=0.00..17677.92 rows=757292 width=8) 
(6 rows) 

, 최대한 빨리 524,289 충돌로, 구체화 된 뷰는 활동하기 시작하고, DELETE 쿼리가 많이된다 더 많은 비용 :

SELECT s.userid 
FROM table1 s 
LEFT JOIN table2 p ON s.userid=p.userid 
WHERE p.userid IS NULL AND s.pointlevel=0 
:

 
explain DELETE FROM table1 WHERE pointLevel = 0 AND userID NOT IN 
(SELECT userID FROM table2 fetch first 524289 rows only); 

    QUERY PLAN 

----------------------------------------------------------------------------------------------------------- 
Delete (cost=0.00..386910.33 rows=21 width=6) 
    -> Index Scan using jslps_userid_nopt on table1 (cost=0.00..386910.33 rows=21 width=6) 
     Filter: ((pointlevel = 0) AND (NOT (SubPlan 1))) 
     SubPlan 1 
      -> Materialize (cost=0.00..16909.24 rows=524289 width=8) 
       -> Limit (cost=0.00..12238.79 rows=524289 width=8) 
         -> Seq Scan on table2 (cost=0.00..17677.92 rows=757292 width=8) (7 rows) 

은 내가 대신 하위 선택 쿼리에서 조인을 사용하여 문제를 해결했다

그러나 materializer가 성능을 크게 떨어 뜨리는 이유를 이해하는 데 여전히 관심이 있습니다.

답변

4

제 생각 엔 rows=524289에 메모리 버퍼가 채워져 있기 때문에 디스크에서 하위 쿼리를 구체화해야합니다. 따라서 시간의 극적인 증가가 필요합니다. 여기

당신은 메모리 버퍼를 구성하는 방법에 대한 자세한 내용을보실 수 있습니다 : 당신이 work_mem로 재생하면 http://www.postgresql.org/docs/9.1/static/runtime-config-resource.html
당신은 쿼리 동작의 차이를 볼 수 있습니다.

그러나 하위 쿼리에서 조인을 사용하면 원본 XYZ 행을 선택하고 검사를 수행하는 것과 비교하여 소스 자체의 행 수를 제한하므로 쿼리 속도를 향상시키는 훨씬 더 좋은 방법입니다.