geschwindigkeiten der verschiedener interfaces

Hallo,

ich baue wie gesagt, eine DB-Anwendung mithilfe des C-Client libpq… und frage mich wie es sein kann, dass eine Abfrage, die in
PQadmin3 ca. 600ms benötigt um die Ergebnisse fertig geliefert zu haben. die gleiche Abfrage auf der Konsole als COPY befehl auf stdout auch ca 600ms
in meinem auf libpq basierenden C-Programm ohne COPY: ca 18sec
in meinem auf libpq basierenden C-Programm mit COPY: ca 30sec
braucht? Wohlgemerkt mache ich in dem C-Programm keinen firlefanz drummrumm, sondern nur Abfrage abfeuern, Daten auslesen nach stdout

Die Abfrage habe ich so gewählt, dass die Ergebnissmenge relativ groß ist um die krassen Unterschiede deutlich zu machen.
Hat hier irgendwer einen Hinweis für mich? Worauf ich achten muss, was ich tun kann? Denn diese Lieferzeiten sind irgendwie nich brauchbar. :frowning:

Viele Grüße
beho

Wie wäre es, wenn du für die jeweiligen Queries ein EXPLAIN (ANALYZE) laufen lässt und uns die Ausgaben samt Query zeigst?

Ausserdem: kannst du den C-Code hier posten, der so langsam ist?

P.S.: in den Icons über dem Eingabefeld gibt es einen CODE Button.

Hallo ads,

bin mir zwar nich sicher was die Abfrage selbst damit zu tun haben soll aber vielleicht überseh ich ja was:

select * from massdata.ssh limit 1000;
explain analyse:
"Limit  (cost=0.00..60.01 rows=1000 width=334) (actual time=0.013..1.614 rows=1000 loops=1)"
"  ->  Seq Scan on ssh  (cost=0.00..5888.24 rows=98124 width=334) (actual time=0.012..0.712 rows=1000 loops=1)"
"Total runtime: 2.158 ms"

der relevante C Code ist

        // Query ohne COPY
	//res = PQexec(conn, "SELECT * FROM massdata.ssh LIMIT 1000;");
        // Query mit COPY
	res = PQexec(conn, "COPY (SELECT * FROM massdata.ssh LIMIT 1000) TO stdout;");
	if (( PQresultStatus( res ) == PGRES_COMMAND_OK ) ||
      ( PQresultStatus( res ) == PGRES_COPY_OUT ))
	{
		while (1) 
		{
			len = PQgetCopyData(conn, &buffer, 0);
			printf("%s\n", buffer);
			if (len > 0 && buffer) {
				PQfreemem(buffer);
			}
			/* we break on len == 0 but note that that should *not* happen,
			because we are not doing an async call (if it happens blame
			postgresql authors :/) */
			else if (len <= 0) break;
		}
	}
	else if(( PQresultStatus( res ) == PGRES_COMMAND_OK ) ||
      ( PQresultStatus( res ) == PGRES_TUPLES_OK ))
   {
		nFields = PQnfields(res);
	    for (i = 0; i < nFields; i++)
			printf("%s", PQfname(res, i));
		printf("\n\n");
		/* next, print out the rows */
		for (i = 0; i < PQntuples(res); i++)
		{
			for (j = 0; j < nFields; j++)
				printf("%s", PQgetvalue(res, i, j));
			printf("\n");
		}

Viele Grüße
beho

Hmm, sieht ja nicht grundsätzlich falsch aus.
Kannst du einen hochauflösenden Zeitwert mit ausgeben? Also irgendetwas mit gettimtofday(), am Start den ersten Wert merken und dann unterwegs schauen, wo genau die Zeit im einzelnen verbraucht wird?

  • Einmal nach dem Query ausführen
  • in der Schleife mit den Ergebnissen pro Ergebnis.

Anhand dessen solltest du erkennen können, wo genau die Zeit bleibt.


Ach, und noch etwas: wie lange läuft dein Programm, wenn du nur die Anfrage stellst und das Programm danach sofort beendest? Also ohne Ergebnisse zu holen?

nur ne kurze Zwischenmeldung:
ich hab jetz ma spasseshalber innerhalb des C-Programmes ebenfalls n EXPLAIN ANALYSE gemacht… die Werte sind die in etwa die Gleichen …
Der Flaschenhals kommt also erst später - offenbar bei der Ausgabe auf der Konsole. Wenn ich nur die Abfrage mache und die Daten nicht ausgebe isses erwartungsgemäß sauschnell. Ich hole jetz ma die Daten, geb sie aber nicht aus…

Ich probier ma was anderes und melde mich später wieder.

Vielen Dank erstmal für eure Hilfe!!!
beho

Ja, so etwas dachte ich mir schon …

Viel Spass beim Debuggen.

also:
wenn ich die Daten hole aber nicht per printf ausgebe isses auch noch sauschnell - so wie es sein sollte.