2015-05-20 6 views
5

auf postgresl 9.0 haben wir eine SQL-Abfrage:Eine postgresql Abfrage wird nicht beenden

SELECT count(*) FROM lane 
WHERE not exists 
    (SELECT 1 FROM id_map 
    WHERE id_map.new_id=lane.lane_id 
    and id_map.column_name='lane_id' 
    and id_map.table_name='lane') 
and lane.lane_id is not null; 

, die in der Regel etwas um 1,5 Sekunden zu beenden dauert. Hier ist der Erklärungs-Plan: http://explain.depesz.com/s/axNN

Manchmal obwohl diese Abfrage hängt und nicht beendet wird. Es kann sogar 11 Stunden lang ohne Erfolg laufen. Es dauert dann 100% der CPU.

Die einzigen Sperren dieser Abfrage sind "AccessShareLock" s und sie sind alle gewährt.

SELECT a.datname, 
     c.relname, 
     l.transactionid, 
     l.mode, 
     l.granted, 
     a.usename, 
     a.current_query, 
     a.query_start, 
     age(now(), a.query_start) AS "age", 
     a.procpid 
    FROM pg_stat_activity a 
    JOIN pg_locks   l ON l.pid = a.procpid 
    JOIN pg_class   c ON c.oid = l.relation 
    ORDER BY a.query_start; 

Die Abfrage wird als Teil eines Java-Prozess ausführen, die der Reihe nach ähnlichen Auswahlabfragen dieses Format mit einem Verbindungspool mit einer Datenbank verbindet und führt:

SELECT count(*) FROM {} WHERE not exists (SELECT 1 FROM id_map WHERE id_map.new_id={}.{} and id_map.column_name='{}' and id_map.table_name='{}') and {}.{} is not null 

keine Updates oder löschen passieren parallel zu diesem Prozess glaube ich nicht, Staubsaugen kann hier das Problem sein. Vor dem Ausführen des gesamten Prozesses (also bevor 6 Abfragen dieser Art ausgeführt werden) wurde eine Analyse für alle Tabellen ausgeführt.

postgres-Protokolle zeigen keinen Eintrag für die lang laufenden Abfragen, da sie nie enden und somit nie protokolliert werden.

Irgendeine Idee, was diese Art von Verhalten verursachen könnte und wie man es verhindern kann?

den Plan erläutern, ohne analysieren:

Aggregate (cost=874337.91..874337.92 rows=1 width=0) 
    -> Nested Loop Anti Join (cost=0.00..870424.70 rows=1565283 width=0) 
     Join Filter: (id_map.new_id = lane.lane_id) 
     -> Seq Scan on lane (cost=0.00..30281.84 rows=1565284 width=8) 
       Filter: (lane_id IS NOT NULL) 
     -> Materialize (cost=0.00..816663.60 rows=1 width=8) 
       -> Seq Scan on id_map (cost=0.00..816663.60 rows=1 width=8) 
        Filter: (((column_name)::text = 'lane_id'::text) AND ((table_name)::text = 'lane'::text)) 
+0

ich hatte gleiches Problem nehmen glaube . Es war keine Postgres-Version - es war Java nicht beendet Verbindung ... 100% CPU von Postgres oder Java? .. Was ist in pg_stat_activity? .. –

+0

100% von Postgres. pg_stat_activity zeigt eine unendliche sql Abfrage – norbitheeviljester

+0

, wenn es zu 100% CPU geht, können Sie den Plan überprüfen? .. Es könnte Nested Loops anstelle von Hash-Joins sein - was bedeuten würde, dass Sie zu wenig RAM für Caching geben ... Ein anderer Ansatz ist " wie neue Statistiken sind "Aber beide sind es wert zu untersuchen, ob der Ausführungsplan sich unterscheidet, wenn er 100% erreicht CPU –

Antwort

5
VACUUM ANALYZE VERBOSE; 

erfrischende Statistiken werden db helfen optimalen Plan zu wählen - nicht verschachtelte Schleifen, die ich mit Java 100% CPU

+0

Ich konnte überprüfen, dass dies in der Tat die Ursache des Problems war. Die verschachtelte Schleife erstellt 1,5 Millionen Sequenz-Scans der Tabelle id_map, die Tage benötigen, um zu beenden. Wenn Sie vor dem Ausführen der Abfrage eine Vakuumanalyse an beiden Tabellen durchführen, wird die Abfrage in weniger als 2 Sekunden abgeschlossen. – norbitheeviljester