Ankündigung

Einklappen
Keine Ankündigung bisher.

Vergleich zweier Tabellen: Laufzeit?!

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • sandemann
    hat ein Thema erstellt Vergleich zweier Tabellen: Laufzeit?!.

    Vergleich zweier Tabellen: Laufzeit?!

    Grüße Euch!

    Habe 2 Tabellen, die preisliste_alt und preisliste_neu. Bekomme die als XLS und importiere die dann als CSV. Wenn die neue liste da ist, möchte ich wissen, welche Artikel im Vergleich zur alten Liste günstiger geworden sind. Das mache ich momentan hier mit:

    Code:
    select * from preisliste_alt left join preisliste_neu on preisliste_alt.Artikelnummer = preisliste_neu.Artikelnummer where preisliste_neu.Verkaufspreis < preisliste_alt.Verkaufspreis
    Leider haben die Tabellen 100.000+ Datensätze und bisher hat es der query noch zu keinen Ergebnis gebracht (mit 2 kleinen Testtabellen hats ganz gut geklappt, deswegen wirds wohl am Volumen der beiden richtigen Tabellen liegen).

    Gibts da auch ne etwas schnellere Lösung als meine? I.d.F. muss es zwar nicht unbedingt schnell gehen, aber jahre lang warten will wohl trotzdem keiner:P

  • Gast-Avatar
    Ein Gast antwortete
    Falls nicht ganz klar geworden ist, was ich meinte, hier noch mal das Kochrezept dazu:


    Code:
    /**
    * Die Speicherengine der Tabellen austauschen
    */
    mysql>ALTER TABLE preisliste_alt ENGINE = MYISAM;
     
    mysql>ALTER TABLE preisliste_neu ENGINE = MYISAM;


    Code:
    /**
    * Index anlegen
    */
    mysql>CREATE INDEX sx_preisliste_alt_01 ON preisliste_alt (artikelnummer, verkaufspreis);
    mysql>CREATE INDEX sx_preisliste_neu_01 ON preisliste_neu (artikelnummer, verkaufspreis);

    Code:
    mysql>ANALYZE TABLE preisliste_alt;
    mysql>ANALYZE TABLE preisliste_neu;


    Code:
    /**
    * Abfrage
    */
    SELECT pn.Artikelnummer, pn.Bezeichnung, pa.Verkaufspreis, pn.verkaufspreis
      FROM preisliste_alt pa
      INNER JOIN preisliste_neu pn
        ON (pn.Artikelnummer = pa.Artikelnummer) 
       AND (pa.Verkaufspreis < pn.Verkaufspreis)
    ORDER BY pn.artikelnummer;

    Viel Erfolg!

    Grüße
    Thomas

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    Also CSV als ENGINE habe ich noch nie verwendet. Vermutlich gehen deshalb keine Indices.

    Kannst Du als ENGINE nicht MYISAM verwenden?
    MySQL :: MySQL 5.1 Referenzhandbuch :: 14.1 Die MyISAM-Speicher-Engine

    Dann gehen die CREATE INDEX .. und alles dürfte deutlich schneller sein.

    Grüße
    Thomas

    Einen Kommentar schreiben:


  • sandemann
    antwortet
    CREATE TABLE `preisliste_alt` ( `Artikelnummer` varchar(100) NOT NULL, `Bezeichnung` varchar(200) NOT NULL, `Verkaufspreis` int(20) NOT NULL ) ENGINE=CSV DEFAULT CHARSET=latin1
    für die zweite Tabelle dann eben preisliste_neu sowie die gleichen spalten

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    Welche Datenbank hast Du da im Einsatz? MySQL?

    Wenn MySQL, dann mal bitte folgendes ausführen:

    Code:
    mysql>SHOW CREATE TABLE preisliste_alt;
    mysql>SHOW CREATE TABLE preisliste_neu;
    Grüße
    Thomas

    Einen Kommentar schreiben:


  • sandemann
    antwortet
    Zitat von thomas_w Beitrag anzeigen
    Hast Du den Tipp mit den Index gelesen (siehe #7)?

    Grüße
    Thomas
    Hab meine Antwort geschrieben ohne Deine zu lesen ... Danke schonmal! Habe keinen Index drauf (too many keys specified). Kann mir eigenltich nicht vorstellen dass die Artikelnummern nicht einzigartig sind (oder liegts daran, dass es ne CSV-Tabelle ist?)! Einen Index definiert zu haben wirkt sich schon stark auf den laufzeit aus, oder?

    Einen Kommentar schreiben:


  • ChrisB
    antwortet
    Zitat von sandemann Beitrag anzeigen
    man wird doch wohl irgendwie 100.000 datensätze durcharbeiten können!
    Du wirst ja wohl auch mal explizite Rückfragen beantworten können ... oder?


    Dass das ohne entsprechende Indexe „ewig“ dauert, ist reichlich normal.

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    Hast Du den Tipp mit den Index gelesen (siehe #7)?

    Grüße
    Thomas

    Einen Kommentar schreiben:


  • sandemann
    antwortet
    also mit folgendem gehts:
    Code:
    SELECT preisliste_alt.Artikelnummer_p, preisliste_alt.Bezeichnung, preisliste_alt.Verkaufspreis
    FROM preisliste_alt
    INNER JOIN preisliste_neu ON (preisliste_alt.Artikelnummer_p = preisliste_neu.Artikelnummer_p) AND (preisliste_alt.Verkaufspreis < preisliste_neu.Verkaufspreis)
    jedoch dauert es auch wieder jahre! ... man wird doch wohl irgendwie 100.000 datensätze durcharbeiten können!

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    Klar ist ein Index wichtiger, ich behaupte dennoch, ein (unnützer) LEFT JOIN ist aufwendiger.

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    Ob ein INNER LOIN oder LEFT JOIN verwendet wird, ist für die Abfragegeschwindigkeit nicht wirklich wichtig. Da müßte erst einmal ein EXPLAIN gemacht werden, um es zu klären. Viel wichtiger ist, ob ein Index auf der Spalte "Artikelnummer" existiert.

    Deine SQL-Abfrage benötigt einen Alias für die Spalten, die in beiden Tabellen vorhanden sind, damit die Datenbank weiß, welche Spalte aus welcher Tabelle sie verwenden soll.

    Code:
    SELECT pn.Artikelnummer, pn.Bezeichnung, pa.Verkaufspreis, pn.verkaufspreis
      FROM preisliste_alt pa
      INNER JOIN preisliste_neu pn
        ON (pn.Artikelnummer = pa.Artikelnummer) 
       AND (pa.Verkaufspreis < pn.Verkaufspreis)
    ORDER BY pn.artikelnummer;
    Existiert ein Index auf die Spalte Artikelnummer?
    Wenn nein, unbedingt einen Index auf den Artikel anlegen (in beiden Tabellen)

    Code:
    CREATE INDEX sx_preisliste_alt_01 ON preisliste_alt (artikelnummer, verkaufspreis);
    CREATE INDEX sx_preisliste_neu_01 ON preisliste_neu (artikelnummer, verkaufspreis);
    Grüße
    Thomas

    Einen Kommentar schreiben:


  • ChrisB
    antwortet
    Zitat von sandemann Beitrag anzeigen
    Dann allerdings mit der Fehlermeldung "#1052 - Column 'Artikelnummer_p' in field list is ambiguous"
    Und wenn du dir ambiguous kurz mal hättest übersetzen lassen ... dann könntest du jetzt auch schon wissen, dass du den Tabellennamen mit angeben musst, wenn eine Spalte in mehreren im Statement verwendeten Tabellen vorkommt.

    Einen Kommentar schreiben:


  • sandemann
    antwortet
    Habs jetzt so:
    Code:
    SELECT Artikelnummer, Bezeichnung, Verkaufspreis
    FROM preisliste_alt
    INNER JOIN preisliste_neu ON (preisliste_alt.Artikelnummer = preisliste_neu.Artikelnummer) AND (preisliste_alt.Verkaufspreis < preisliste_neu.Verkaufspreis)
    Dann allerdings mit der Fehlermeldung "#1052 - Column 'Artikelnummer_p' in field list is ambiguous" ... In den Beispielen die ich gegooglet hatte wars aber das selbe Schema ... Würd mich freuen wenn jemand den Code berichtigen könnte!

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    Einen inner join verwenden.

    Einen Kommentar schreiben:


  • sandemann
    antwortet
    Zitat von nikosch Beitrag anzeigen
    Ein left join isat unnötig, weil man nicht vorhandene Artikel ohnehin nicht miteinander vergleichen kann.
    wie würdest du es denn dann machen? bin grad leider etwas ratlos....

    Einen Kommentar schreiben:

Lädt...
X