Chris: LEFT JOIN viel zu langsam

Hallo,

irgendwie ist mein SELECT ziemlich langsam, etliche Sekunden und ich weiß nicht so recht woran das liegen könnte.

  
SELECT a.lagerstatus, a.herstellernr, a.hide_shop, b.actebis_herstlnr, b.actebis_lagerbestand, c.also_herstnr, c.also_bestand, d.techdata_herstlnr, d.techdata_lagerbestand, e.namede, e.kategorie, e.hide_shop, f.ingram_bestand, f.ingram_herstnr, g.bcom_bestand, g.bcom_herstnr, GREATEST(b.actebis_lagerbestand, c.also_bestand, d.techdata_lagerbestand, f.ingram_bestand, g.bcom_bestand) AS MaxBestand  
FROM tspi_article a  
LEFT JOIN tspi_actebis b ON (a.herstellernr = b.actebis_herstlnr OR a.herstellernr2 = b.actebis_herstlnr OR a.herstellernr3 = b.actebis_herstlnr)  
LEFT JOIN tspi_also c ON (a.herstellernr = c.also_herstnr OR a.herstellernr2 = c.also_herstnr OR a.herstellernr3 = c.also_herstnr)  
LEFT JOIN tspi_techdata d ON (a.herstellernr = d.techdata_herstlnr OR a.herstellernr2 = d.techdata_herstlnr OR a.herstellernr3 = d.techdata_herstlnr)  
LEFT JOIN tspi_ingram f ON (a.herstellernr = f.ingram_herstnr OR a.herstellernr2 = f.ingram_herstnr OR a.herstellernr3 = f.ingram_herstnr)  
LEFT JOIN tspi_article_group e ON a.gruppe = e.namede  
LEFT JOIN tspi_bcom g ON (a.herstellernr = g.bcom_herstnr OR a.herstellernr2 = g.bcom_herstnr OR a.herstellernr3 = g.bcom_herstnr)  
WHERE a.lagerstatus!='Sofort lieferbar'  
AND a.hide_shop=0  
AND e.hide_shop=0  
AND e.kategorie!='Gutscheine'  
AND e.kategorie!='Zubehör'  
ORDER BY 'MaxBestand' DESC  

Ein explain gibt folgendes aus:

+-------+------+-------------------+-----------+---------+-----------+-------+----------------------------------------------+
| table | type | possible_keys     | key       | key_len | ref       | rows  | Extra                                        |
+-------+------+-------------------+-----------+---------+-----------+-------+----------------------------------------------+
| a     | ref  | gruppe,hide_shop  | hide_shop | 4       | const     | 1961  | Using where; Using temporary; Using filesort |
| e     | ref  | name,hide_shop    | name      | 50      | a.gruppe  | 1     | Using where                                  |
| b     | ALL  | actebis_herstlnr  | NULL      | NULL    | NULL      | 555   |                                              |
| c     | ALL  | also_herstnr      | NULL      | NULL    | NULL      | 582   |                                              |
| d     | ALL  | techdata_herstlnr | NULL      | NULL    | NULL      | 556   |                                              |
| f     | ALL  | ingram_herstnr    | NULL      | NULL    | NULL      | 537   |                                              |
| g     | ALL  | bcom_herstnr      | NULL      | NULL    | NULL      | 97    |                                              |
+-------+------+-------------------+-----------+---------+-----------+-------+----------------------------------------------+

Die 5 Tabellen die den type "ALL" haben, sind vom Aufbau her alle gleich:

  
CREATE TABLE tspi_bcom (  
  bcom_id int(10) NOT NULL auto_increment,  
  bcom_artnr varchar(255) NOT NULL default '',  
  bcom_herstnr varchar(255) NOT NULL default '',  
  bcom_ep varchar(255) NOT NULL default '',  
  bcom_bestand varchar(255) NOT NULL default '',  
  bcom_beschreibung text NOT NULL,  
  bcom_herstlname varchar(255) NOT NULL default '',  
  PRIMARY KEY  (bcom_id),  
  UNIQUE KEY bcom_id (bcom_id),  
  KEY bcom_herstnr (bcom_herstnr),  
  KEY bcom_bestand (bcom_bestand),  
  KEY bcom_ep (bcom_ep)  
) TYPE=MyISAM;  

DB-Version ist: 4.00.25

Wo könnte ich nun was verbessern?

Danke und Grüße

Chris

  1. Die 5 Tabellen die den type "ALL" haben, sind vom Aufbau her alle gleich:

    Wo könnte ich nun was verbessern?

    Natürlich die Tabellen in eine einzige zusammenfassen, "OR"-Joins finde ich übrigens ziemlich uncool.

    1. Hi

      Natürlich die Tabellen in eine einzige zusammenfassen, "OR"-Joins finde ich übrigens ziemlich uncool.

      Klar, aber dann kann ich eigentlich schlechter vergleichen. OR-Joins sind sicherlich uncool, aber ich hatte dazu keine andere Lösung gefunden...

      1. Natürlich die Tabellen in eine einzige zusammenfassen, ...

        Klar, aber dann kann ich eigentlich schlechter vergleichen.

        Ich behauptete das Gegenteil.   ;)

        1. Soso ;)

          Ich behauptete das Gegenteil.   ;)

          Magst du mir auch ein Beispiel zeigen? Ich habe schon mal eine Tabelle angelegt, für alle Distributoren:

            
          CREATE TABLE tspi_dis (  
            dis_id int(10) NOT NULL auto_increment,  
            dis_name int(5) NOT NULL default '0',  
            dis_nr varchar(255) NOT NULL default '',  
            dis_ep varchar(255) NOT NULL default '',  
            dis_bestand varchar(255) NOT NULL default '',  
            dis_text text NOT NULL,  
            dis_herstlname varchar(255) NOT NULL default '',  
            PRIMARY KEY  (dis_id),  
            UNIQUE KEY dis_id (dis_id)  
          ) TYPE=MyISAM;  
          
          

          dis_name ist die ID des jeweiligen Distributors. dis_nr die Hersteller-Nr., ep der Preis usw. Wie kann ich dann, wenn alle Daten in einer Tabelle sind, die Daten mit der Tabelle a vergleichen?
          Geht ja alles über die Hersteller-Nr. bzw. dis_nr, a.herstellernr, a.herstellernr2, a.herstellernr3 und die müsste in der Tablle tspi_dis ja dann mehrfach vorkommen.

          Wahrscheinlich seh ich nur gerade kein Licht am Ende des Tunnels...

          1. Wahrscheinlich seh ich nur gerade kein Licht am Ende des Tunnels...

            Gut, wenn Du die 5 Tabellen zusammenführst und das DF "Herstellerkennung" beifügst, bist Du schon mal einen Schritt weiter, jetzt hast Du vermutlich Probleme mit der Verzeigerung der Tabellen über Fremdschlüssel und dem Setzen von Primärschlüsseln? Ich kann mich nicht in die Problematik hineinversetzen, da mir die Semantik der Tabellenstrukturen fremd ist (und ich auch nicht viel Bock darauf habe ;).

            Aber, sei beruhigt, Deine Probleme sind gering. Vielleicht schreibst Du mal ganz abstrakt, was nicht funzt.

            1. Aber, sei beruhigt, Deine Probleme sind gering. Vielleicht schreibst Du mal ganz abstrakt, was nicht funzt.

              Puh ok, ich habe es nun folgendermaßen:

                
              SELECT a.herstellernr, a.herstellernr2, a.herstellernr3, b.dis_nr, b.dis_bestand, b.dis_name FROM tspi_article a, tspi_distributor b WHERE (a.herstellernr = b.dis_nr OR a.herstellernr2 = b.dis_nr OR a.herstellernr3 = b.dis_nr) AND a.herstellernr!="" AND a.lagerstatus!='Sofort lieferbar' AND a.hide_shop=0  
              
              

              So bekomme ich aber unter einander die ganzen gleichen Nummern angezeigt:

              +--------------+---------------+---------------+-------------+-------------+----------+
              | herstellernr | herstellernr2 | herstellernr3 | dis_nr      | dis_bestand | dis_name |
              +--------------+---------------+---------------+-------------+-------------+----------+
              | RH460EA#ABD  |               |               | RH460EA#ABD | 0           | 13       |
              | RH460EA#ABD  |               |               | RH460EA#ABD | 2           | 70       |
              | RH460EA#ABD  |               |               | RH460EA#ABD | 6           | 56       |
              +--------------+---------------+---------------+-------------+-------------+----------+

              Wie kann ich das nun so grupieren, dass nur noch in einer Zeile mit der jeweiligen Hersteller-Nr alles angezeigt wird, wo der dis_bestand am Größten ist?

              1. Wie kann ich das nun so grupieren, dass nur noch in einer Zeile mit der jeweiligen Hersteller-Nr alles angezeigt wird, wo der dis_bestand am Größten ist?

                Mit HAVING oder MAX().

  2. yo,

    dein problem ist aller wahrscheinlichkeit weitreichender, als einfach nur eine sql abfrage zu finden. die OR verknüpfungen würde man eventuell leicht mit UNION ALL Mengenoperatoren rausbekommen.

    die Problematik liegt aber meiner meinung nach eher in deinem daten-design, stichwort mehrere hesrtellernummern in verschiedenen spalten. wenn das noch änderbar ist, würde ich an deiner stelle erst einmal das design gerade biegen, dann werden sich die folgeprobleme von alleine lösen.

    Ilja