6

PostgreSQL 9.0.4'te çalıştırmam gereken bir DELETE sorgum var. Bir alt seçim sorgusunda 524,289 satır çarpana kadar performans olduğunu buluyorum. ÖrneğinPostgres Materialize, silme sorgusunda kötü performansa neden oluyor

, 524,288 kullanılan hiçbir materialized görüş mevcuttur ve maliyet oldukça iyi görünüyor: Ancak

 
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) 

, en kısa sürede 524,289 vurmak gibi hayata bakış devreye girer ve SİL sorgu çok olur daha masraflı:

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) 

Ben yerine alt seçme sorguda JOIN kullanarak soruna çalıştı

Ancak, materyalizasyonun neden performansı önemli ölçüde azalttığını anlamakla hala ilgileniyorum.

cevap

4

Tahminimce, rows=524289 adresindeki bellek arabelleği doldurulduğundan, alt dizinin diskte gerçekleştirilmesi gerekir. Bu nedenle gerekli zamandaki dramatik artış. İşte

Eğer bellek tamponları yapılandırma hakkında daha fazla bilgi edinebilirsiniz: Eğer work_mem ile oynarsanız http://www.postgresql.org/docs/9.1/static/runtime-config-resource.html
sorgu davranış farkını göreceksiniz.

Ancak, alt sorguda birleştirme, sorguyu hızlandırmak için çok daha iyi bir yoldur, çünkü kaynaktaki satırların sayısını sınırlandırıyorsunuz çünkü sadece ilk XYZ satırlarını seçip kontrolleri gerçekleştiriyorsunuz.

İlgili konular