2016-12-18 3 views
1

ich meinen Kopf seit gestern auf diese zu schlagen, und ich understanf nicht, was los ist:einfache Lookup-Abfrage sehr langsam auf Postgres, schnell in MySQL

Ich bin ein dimensionales Schema für ein Data-Warehousing-Projekt bevölkern, mit Pentaho Kettle, um ein "dimension lookup/update" durchzuführen, welches grundsätzlich nach vorhandenen Zeilen in einer Dimensionstabelle sucht, die nicht existierenden einfügt und den technischen Schlüssel zurückgibt.

Die Dimensionstabelle selbst ist sehr einfach:

CREATE TABLE dim_loan 
(
    _tech_id INTEGER NOT NULL, 

    loan_id INTEGER, 
    type TEXT, 
    interest_rate_type TEXT, 

    _dim_project_id integer, 

    _validity_from date, 
    _validity_to date, 
    _version integer, 

    PRIMARY KEY (_tech_id) 
); 
CREATE INDEX dim_loan_pk_idx ON dim_loan USING btree (_tech_id); 
CREATE INDEX dim_loan_compound_idx ON dim_loan USING btree (loan_id, _dim_project_id, _validity_from, _validity_to); 

Die Tabelle am Ende des Prozesses enthalten soll, um 650k Zeilen. Die Transformationen beginnen schnell (ish) bei etwa 1500 Zeilen/Sek. Die Leistung sinkt stetig und erreicht 50 Zeilen/Sek. Bis die Tabelle ungefähr 50k Zeilen hat. Die Abfragen, die Kettle wie folgt aussieht:

SELECT _tech_id, _version, "type" AS "Loan Type", interest_rate_type AS int_rate, _validity_from, _validity_to FROM "public".dim_loan WHERE loan_id = $1 AND _dim_project_id = $2 AND $3 >= _validity_from AND $4 < _validity_to 

Der Anfrageplaner eine Ausführungszeit von 0,1 msec schätzt:

"Index Scan using dim_loan_compound_idx on dim_loan (cost=0.42..7.97 rows=1 width=42) (actual time=0.043..0.043 rows=0 loops=1)" 
" Index Cond: ((loan_id = 1) AND (_dim_project_id = 2) AND ('2016-01-01'::date >= _validity_from) AND ('2016-01-01'::date < _validity_to))" 
"Total runtime: 0.078 ms" 

Natürlich realen Ausführungszeiten sind sehr unterschiedlich, um 10 ms, was nicht akzeptabel ist . Aktivieren Lügt für langsame Abfragen mit auto_explain I mit erhöhter Frequenz Einträgen wie diese:

Seq Scan on dim_loan (cost=0.00..2354.21 rows=12 width=52) 
      Filter: (($3 >= _validity_from) AND ($4 < _validity_to) AND (_dim_project_id = $2) AND ((loan_id)::double precision = $1)) 
< 2016-12-18 21:30:19.859 CET >LOG: duration: 14.260 ms plan: 
     Query Text: SELECT _tech_id, _version, "type" AS "Loan Type", interest_rate_type AS int_rate, _validity_from, _validity_to FROM "public".dim_loan WHERE loan_id = $1 AND _dim_project_id = $2 AND $3 >= _validity_from 
     AND $4 < _validity_to 

die ohnehin nicht der ganzen Geschichte erzählen, da es nicht nur diese Abfragen sind, die langsam laufen, aber alle von ihnen. Natürlich habe ich versucht, die Speicher-Parameter bis zu dummen Mengen ohne wirklichen Unterschied in der Leistung zu optimieren, ich habe auch die neuste Version 9.6 ausprobiert, die das gleiche Verhalten wie 9.3 zeigte, was ich verwende.

Die gleiche Transformation, auf einer MySQL-Datenbank mit den gleichen Indizes, läuft glücklich mit 5000 Zeilen/Sek von Anfang bis Ende. Ich möchte wirklich PG verwenden und ich bin mir sicher, dass es etwas Triviales ist, aber was !? Vielleicht etwas mit dem JDBC-Treiber? Ich habe überprüft, dass es immer eine einzige Verbindung verwendet, so ist es nicht einmal eine Verbindung Overhead-Problem ...

+0

Warum wird 'loan_id' auf doppelte Genauigkeit angewendet? –

+0

Spot auf Richard, danke! –

+0

Die Ausgabe von 'explain analyze' ist ** nicht ** eine" geschätzte "Ausführungszeit. Es ist die ** tatsächliche ** Ausführungszeit, die die Abfrage ** auf dem Server ** dauerte - ohne die Ergebnisse an den Client zu senden. Wenn 'explain analyze' 0,078ms angibt und Sie 10ms auf der Client-Seite messen, ist der Unterschied die Zeit, die zum Senden der Daten benötigt wird (obwohl das ein wenig überraschend ist, wenn keine Zeilen zurückgegeben werden). –

Antwort

2

Gerade herausgefunden, dass die Ursache ist in der Tat Darlehens-ID zu verdoppeln, was natürlich den Index nutzlos gemacht ! Der Grund ist eine falsche Annahme, die Kettle für die Metadaten dieser Spalte getroffen hat, die aus einer Excel-Datei stammen. Jetzt ist die Leistung auf Augenhöhe mit MySQL! Happy days

Verwandte Themen