2016-06-26 2 views
1

Hier zu nehmen ist meine Tabelle:SELECT * aus einfacher Tabelle mit 50k Aufzeichnungen scheint 40 Sekunden

CREATE TABLE public.logs (
    logid bigint NOT NULL DEFAULT nextval('applog_logid_seq'::regclass), 
    applicationname character varying(50), 
    loglevel character varying(10), 
    logmessage character varying(500), 
    stacktrace character varying(4096), 
    occurredon timestamp without time zone, 
    loggedon timestamp without time zone, 
    username character varying(50), 
    groupname character varying(50), 
    useragent character varying(512), 
    CONSTRAINT applog_pkey PRIMARY KEY (logid) 
); 

Wenn ich laufe SELECT *... drauf, dauert es 40 Sekunden 50000 Zeilen auf meinem lokalen Rechner zurückzukehren. Ich habe die gleiche Tabelle auf einer lokalen Installation von SQL Server, und das dauert weniger als eine Sekunde, um die gleiche Menge an Daten zurückzugeben.

Ich bin in der Mitte einer Bewertung von PostgreSQL für unseren neuen Stapel und das ist sehr beunruhigend für mich. Warum mache ich falsch/warum ist PostgreSQL so langsam?

Edit:

Hier ist, was ich von EXPLAIN (BUFFERS, ANALYZE, TIMING OFF) SELECT * FROM public.logs erhalten:

enter image description here

So sieht es aus wie der Server in dieser etwa 6 ms für die Ausführung geht. Ich denke, das bedeutet, dass der gesamte Overhead in pgAdmin III liegt, aber wie kann SSMS das so viel schneller machen?

+0

Hat diese Tabelle starken "UPDATE" oder "DELETE" Datenverkehr? – jmelesky

+0

Führen Sie SQL Server und PostgreSQL gleichzeitig auf Ihrem Computer aus? Wie viel RAM haben Sie? – Alex

+0

Sind Sie sicher, dass Sie in beiden Fällen tatsächlich das gesamte Resultset durchlaufen? Oder ist es möglich, dass Sie zum Beispiel nur die ersten x Zeilen in SQL Server abrufen? Und wenn PostgreSQL nicht lokal läuft, dann besteht kein Zweifel, dass dies kein fairer Vergleich ist. – sstan

Antwort

3

Vielen Dank für die Hilfe aller in mir zu reden von der Klippe hinunter :)

komponierte ich einen Knoten Konsole App-Anwendung, die meine Bedenken ins Bett legt. Tatsächlich schlägt meine Postres-Instanz SQL Server um etwa 50% (wie @Guillaume F. darauf hingewiesen hat). Im gleichen Client hier sind die Ergebnisse:

Postres (RDS) Abfrage Dauer: 7062ms

Postres (RDS) zurückgegebenen Zeilen: 50000

Postgres (Lokal) Abfrage Dauer: 1919ms

Postgres (lokal) zurückgegebenen Zeilen: 46154

MSSQL (local) Abfrage Dauer: 4681ms

MSSQL (local) zurückgegebenen Zeilen: 50000

Hier ist die Beispielanwendung, wenn jemand in dem Duplizieren meiner Ergebnisse in ihrer eigenen Umgebung interessiert ist:

'use strict'; 

let pgp = require('pg-promise')(); 
let db = pgp("postgres://username:[email protected]:5432/db"); 
let localdb = pgp("postgres://username:[email protected]:5432/db"); 
var mssql = require('mssql'); 

let start = new Date(); 
db.query('select * from logs').then((result) => { 
    console.log("Postres (RDS) query duration: " + (new Date() - start) + "ms"); 
    console.log("Postres (RDS) rows returned: " + result.length); 
    console.log(""); 

    let localstart = new Date(); 
    localdb.query('select * from logs').then((localresult) => { 
     console.log("Postgres (Local) query duration: " + (new Date() - localstart) + "ms"); 
     console.log("Postgres (Local) rows returned: " + localresult.length); 
     console.log(""); 

     var config = { 
      user: 'username', 
      password: 'password', 
      server: 'server', // You can use 'localhost\\instance' to connect to named instance 
      database: 'db' 
     }; 

     mssql.connect(config).then(function() { 

      // Query 
      let localMSSqlStart = new Date(); 
      new mssql.Request().query('select TOP 50000 * from dbo.AppLog ORDER BY 1 DESC').then(function (recordset) { 
       console.log("MSSQL (local) query duration: " + (new Date() - localMSSqlStart) + "ms"); 
       console.log("MSSQL (local) rows returned: " + result.length); 
       console.log(""); 
      }).catch(function (err) { 

       // ... query error checks 
       console.log("Problem querying MSSQL: " + err); 
      }); 
     }).catch(function (err) { 

      // ... connect error checks 
      console.log("Problem connecting to MSSQL: " + err); 
     }); 
    }); 
}); 

EDIT: (von pg-promise Autor)

Nebenbei, dies ist nur um zu zeigen, wie PostgreSQL in einer zivilisierteren Art und Weise Benchmark:

let pgp = require('pg-promise')(); 
let db = pgp("postgres://username:[email protected]:5432/db"); 
let localdb = pgp("postgres://username:[email protected]:5432/db"); 

db.result('select * from logs') 
    .then(r => { 
     console.log("Postres (RDS) rows returned:", r.rows.length); 
     console.log("Postres (RDS) query duration:", r.duration + 'ms\n'); 
     return localdb.result('select * from logs') 
      .then(r => { 
       console.log("Postgres (Local) rows returned:", r.rows.length); 
       console.log("Postgres (Local) query duration:", r.duration + 'ms\n'); 
      }) 
    }) 
    .catch(error=> { 
     console.log(error); 
    }); 

Der Vorteil der Verwendung der Methode result für Benchmarks ist, dass pg-promise automatisch die Result mit der Eigenschaft duration erweitert.

+0

Danke @ vitaly-t. Ich bin auch dankbar für Ihre Arbeit an pg-promise. Tolles Modul! –

3

Wie wir vermutet haben, und wie wir von der EXPLAIN Ausgabe sehen können, wird fast keine Zeit auf dem Server verbracht, sondern für die Übertragung (Netzwerklatenz) und Rendern der Ausgabe. Wir sehen 7 ms in der EXPLAIN Ausgabe, die Sie der Frage hinzugefügt haben.

Das Rendern großer Textmengen in pgAdmin III ist nicht sehr schnell. Zwei Tipps:

  1. Meistens müssen Sie nicht den ganzen Inhalt von großen Spalten sehen. Um die Dinge zu beschleunigen, können Sie in pgAdmin III eine maximale Anzahl von Zeichen einstellen. Aber nicht bekommen, verwirrt, wenn Sie nur das führende Fragment von langen Strings sehen:

  2. pgAdmin 4 Beta 2 aus (2016.06.24). Noch nicht freigegeben, aber da es sich um eine komplette Neuschreibleistung handelt, kann sich das erheblich unterscheiden. More on project's site.

Verwandte Themen