Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 16 von 16

Thema: Performance bei vielen Selects gegenüber MySQL

  1. #11
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von Fabi Beitrag anzeigen
    Hallo,

    wie versprochen melde ich mich zurück. Vorab: ich bin schon etwas enttäuscht von der performance und erhoffe mir evtl. noch ein paar Tipps.

    Das Testszenario

    - Als Testhardware dient mein Laptop (i52410m, 4GB RAM, Win7)
    - MySQL Version: 5.5
    - Postgres Version: 9.0.4
    - Die Testanwendung ist in Java geschrieben und bindet beide Datenbanken per JDBC an.
    - Die Anwendung nutzt Threads. Es laufen immer 3 Worker Threads gleichzeitig.
    - Das führt dazu das ich 3 Postgres Prozesse mit je 25% CPU LAst habe, bzw. einen mysqld Prozess mit 75%
    - Auf dem 4 logischen Core nimmt sich java 1-3% CPU
    - Die Worker Threads durchlaufen mehrere Zählschleifen um am Ende eine Stored Procedure (SP) mit 6 double und einer String Variable aufzurufen

    Hier die MySQL SP (Die Namen aller Variablen und Bezeichnungen habe ich anonymisiert)

    CREATE DEFINER=`root`@`localhost` PROCEDURE `analyze`(IN `minOne` DOUBLE, IN `maxOne` DOUBLE, IN `minTwo` DOUBLE, IN `maxTwo` DOUBLE, IN `minThree` DOUBLE, IN `maxThree` DOUBLE, IN `dataType` VARCHAR(5))

    BEGIN

    SELECT
    SUM(IF(specialValue = 1, 1, 0) / COUNT(*)),
    SUM(resultValue),
    AVG(
    resultValue),
    STD(
    resultValue),
    VARIANCE(
    resultValue)
    FROM Analysis
    WHERE
    firstValue BETWEEN minOne AND maxOne
    AND secondValue BETWEEN minTwo AND maxTwo
    AND thirdValue BETWEEN minThree AND maxThree
    AND origin = dataType;

    END


    Die dazugehörige Tabelle "Analysis" in der MySQL Version:

    CREATE TABLE `Analysis` (
    `measured` TIMESTAMP NULL DEFAULT NULL,
    `firstValue` DOUBLE UNSIGNED NULL DEFAULT NULL,
    `secondValue` DOUBLE UNSIGNED NULL DEFAULT NULL,
    `thirdValue` DOUBLE NULL DEFAULT NULL,
    `specialValue` TINYINT(1) UNSIGNED NULL DEFAULT NULL,
    `resultValue` DOUBLE NULL DEFAULT NULL,
    `origin` VARCHAR(5) NULL DEFAULT NULL
    )
    COLLATE='utf8_general_ci'
    ENGINE=MEMORY
    ROW_FORMAT=DEFAULT


    Und hier die selbe function in Postgres (Feedback welcome!)

    CREATE OR REPLACE FUNCTION analyze("minOne" double precision, "maxOne" double precision, "minTwo" double precision, "maxTwo" double precision, "minThree" double precision, "maxThree" double precision, "dataType" character varying)
    RETURNS SETOF record AS
    $BODY$

    BEGIN

    RETURN QUERY
    SELECT
    CAST(SUM(CASE WHEN specialValue = 1 THEN 1 ELSE 0 END) AS double precision) / CAST(COUNT(*) AS double precision),
    SUM(
    resultValue),
    AVG(
    resultValue),
    STDDEV(
    resultValue),
    VARIANCE(
    resultValue)
    FROM Analysis
    WHERE
    firstValue BETWEEN $1 AND $2
    AND secondValue BETWEEN $3 AND $4
    AND thirdValue BETWEEN $5 AND $6
    AND origin = $7;

    RETURN ;

    END;$BODY$
    LANGUAGE plpgsql VOLATILE
    COST 100
    ROWS 1000;
    ALTER FUNCTION analyze(double precision, double precision, double precision, double precision, double precision, double precision, character varying) OWNER TO postgres;

    Und hier die Tabelle Analysis in der Postgres Version (mit einem zusätzlichen Primary Key):

    CREATE TABLE analysis
    (
    measured timestamp without time zone,
    firstValue double precision,
    secondValue double precision,
    thirdValue double precision,
    specialValue integer,
    resultValue double precision,
    origin character varying(5) DEFAULT NULL::character varying,
    id serial NOT NULL,
    CONSTRAINT id PRIMARY KEY (id)
    )
    WITH (
    OIDS=FALSE
    );
    ALTER TABLE analysis OWNER TO postgres;


    Ergebnis:

    Die Tabellen wurden jeweils mit den gleichen 12000 Zeilen befüllt. Die Worker Threads bekamen die gleiche Payload.

    Die MySQL Variante ist in 50min durchgerechnet

    Die Postgres Variante brauchte über 5 Stunden.

    Interpretation

    Also ich glaube, dass MySQL bei diesem Anwendungsfall mit dem MEMORY Table punkten kann. Da es in Postgres ja
    keine unterschiedlichen Tabellentypen gibt, schien es mir eine gute Idee effective_cache_size, shared buffers und work_mem zu erhöhen,
    was aber offensichtlich nicht viel gebracht hat.

    Da ich ncoh sehr wenig Erfahrung mit Postgres habe, bin ich für Feedback dankbar.

    Viele Grüße,

    Fabi

    Hast Du gar keine Indexe?

    Hast Du Dir mal den Plan angeschaut?


    Thema temp. Tabellen etc.: PG 9.1 bringt unlogged Tables mit, das könnte für Dich u.U. recht nützlich sein. Aber darauf brauchst erst mal nicht zu warten, ein EXPLAIN ANALYSE und dann das, was in Deiner Function drin steht. Ich sehe da schone WHERE-Conditions, aber halt keine Indexe auf den Spalten.


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  2. #12
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von ads Beitrag anzeigen
    Also vergleichst du Äpfel mit Tomaten? Super Konzept.

    Schau dir mal temporäre Tabellen an, die könnten dir ein Stück weiterhelfen.
    Da bin ich mir nicht ganz so sicher - werden diese Tabellen in anderen Transaktionen / Verbindungen benötigt oder NUR in der grad laufenden Session?


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  3. #13
    ads
    ads ist offline Super-Moderator
    Registriert seit
    08.02.2006
    Ort
    MD
    Beiträge
    4.056

    Standard

    Nur in der gerade laufenden - aber er will ja quasi Qubes für verschiedene Benutzer vorberechnen, damit die dann darauf ihre eigentlichen Reports fahren können.
    Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören

    Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

    PostgreSQL Service & Support

  4. #14
    Fabi ist offline Neuer Benutzer
    Registriert seit
    20.07.2011
    Beiträge
    7

    Standard

    Hi,

    Ich habe heute morgen das ganze auf temporäre Tabellen umgestellt und Indizes für firstValue, SecondValue, ThirdValue, resultValue und origin angelegt und einen neuen Testlauf gestartet.

    Es lief gerade in 22min durch. Vielen Dank für die Tipps. Ich hab gerade nicht so viel Zeit, da ich nen vollen Tag heute hab. Ich schreibe nochmal was wenn ich zuhause bin heute Abend.

  5. #15
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von Fabi Beitrag anzeigen
    Hi,

    Ich habe heute morgen das ganze auf temporäre Tabellen umgestellt und Indizes für firstValue, SecondValue, ThirdValue, resultValue und origin angelegt und einen neuen Testlauf gestartet.

    Es lief gerade in 22min durch. Vielen Dank für die Tipps. Ich hab gerade nicht so viel Zeit, da ich nen vollen Tag heute hab. Ich schreibe nochmal was wenn ich zuhause bin heute Abend.
    Na schau an, MySQL braucht 50 Minuten, PG 22.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  6. #16
    Fabi ist offline Neuer Benutzer
    Registriert seit
    20.07.2011
    Beiträge
    7

    Standard

    Hallo,

    Ja ich bin wirklich sehr positiv überrascht, dass Postgres SO zugelegt hat. Bisher habe ich ja nur den Kern migriert um den Vergleich machen zu können. Jetzt werd ich wohl auch die Zeit investieren den Rest "rüber" zu bringen. Danke nochmal für die Tipps.

    Abschließend hier nochmal der Temporary Tabel der jetzt von jedem Worker Thread erst angelegt und befüllt wird bevor er anfängt zu rechnen.

    CREATE TEMPORARY TABLE analysis
    (
    measured timestamp without time zone,
    firstValue double precision,
    secondValue double precision,
    thirdValue double precision,
    specialValue integer,
    resultValue double precision,
    origin character varying(5) DEFAULT NULL::character varying,
    id serial NOT NULL,
    CONSTRAINT id PRIMARY KEY (id)
    )
    WITH (
    OIDS=FALSE
    );
    ALTER TABLE analysis OWNER TO postgres;

    CREATE INDEX "firstValueIndex"
    ON analysis
    USING btree
    (firstValue);

    CREATE INDEX "secondValueIndex"
    ON analysis
    USING btree
    (secondValue);

    CREATE INDEX "thirdValueIndex"
    ON analysis
    USING btree
    (thirdValue);

    CREATE INDEX "originIndex"
    ON analysis
    USING btree
    (origin);

    CREATE INDEX "resultValueIndex"
    ON analysis
    USING btree
    (resultValue);
    Geändert von Fabi (27.07.2011 um 21:59 Uhr) Grund: Typos

Seite 2 von 2 ErsteErste 12

Ähnliche Themen

  1. Like mit vielen werten
    Von Painstation im Forum SQL
    Antworten: 4
    Letzter Beitrag: 26.07.2010, 09:17
  2. 2 Selects verknüpfen
    Von msamesch im Forum SQL
    Antworten: 3
    Letzter Beitrag: 28.10.2009, 12:55
  3. Performance bei parallelen SELECTs
    Von henry.hinze im Forum Konfiguration
    Antworten: 1
    Letzter Beitrag: 16.02.2007, 12:58
  4. Antworten: 1
    Letzter Beitrag: 04.02.2007, 13:31
  5. MySql-->Postgresql ==> schlechtere Performance
    Von hretif im Forum Migration
    Antworten: 9
    Letzter Beitrag: 09.11.2006, 18:37

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum