MySQL Optimierung

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

  • MySQL Optimierung

    Hallo,

    ich habe ein funktionierendes Script, aber das ist ziemlich viel unprofessionelles Gebastel und daher sehr ressourcenlastig. Bekomme schon immer Schimpfe vom Webhoster und die Bitte, das mal zu optimieren. Mit Inner Joins habe ich mich schon ansatzweise beschäftigt, aber dies hier ist zu komplex für mich, also vielleicht kann mir jemand unter die Arme greifen?!

    Hier ist mal so eine Abfrage, die angeblich 10 Minuten dauert, bis sie beendet ist (Datenbank hat insgesamt 126 MB)


    PHP-Code:
    SELECT `products_description`.`products_name`,`categories_description`.`categories_name`, `manufacturers`.`manufacturers_name`
    FROM productsproducts_descriptionproducts_to_categoriescategoriescategories_descriptionlanguagesmanufacturersconfiguration 
    WHERE products
    .products_id products_description.products_id 
    AND products_description.language_id languages.languages_id 
    AND products_description.products_id products_to_categories.products_id 
    AND products_to_categories.categories_id categories.categories_id 
    AND categories.categories_id categories_description.categories_id
    AND categories_description.language_id languages.languages_id 
    AND products.manufacturers_id manufacturers.manufacturers_id 
    AND products.products_status =
    AND languages.code configuration.configuration_value 
    AND categories.categories_id '96' 
    Hoffe, da blickt man durch

  • #2
    Hallo,

    das ist ein bösartiges Kreuzprodukt, das mit Where notdürftig gefiltert wird. Verwende stattdessen
    Code:
    JOIN ... ON ... = ...
    und indiziere alle Spalten, die nach ON verglichen werden.

    Gruß,

    Amica
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      Wie verknüpft man verschiedene inner joins?

      Hi Amica,

      danke für die schnelle Antwort. Einfache innner joins kann ich schon, aber wie kann ich die inner joins meiner Abfrage verknüpfen? Es muss ja nach mehreren Spalten gejoint werden.

      So funktionierts nicht:

      PHP-Code:
      SELECT products_description.products_namecategories_description.categories_name from products_description
      categories_description JOIN products on products_description.products_id products.products_id AND
      products_to_categories on categories_description.categories_id products_to_categories.categories_id 
      So auch nicht:

      PHP-Code:
      SELECT products_description.products_namecategories_description.categories_name from products_description
      categories_description JOIN productsproducts_to_categories on products_description.products_id products.products_id
      categories_description.categories_id products_to_categories.categories_id 
      Ich weiß, ich bin ein MySQL Noob. Tutorials und Beispiele finde ich nur für den Abgleich eines Kriteriums. Wäre echt nett, wenn du mir ein gekürztes Beispiel aus meiner Ketten-Where-Abfrage machen könntest.

      Kommentar


      • #4
        Beispiel: Eine Person hat beliebig viele Telefonnummern, kann sich aber auch eine Nummer mit anderen Personen (Familie) teilen. Eine Telefonnummer kann dabei aber auch ein Fax oder ein Mobiltelefon sein, hat also einen bestimmten Typ. Wenn man das abbildet, ergibt sich folgende Struktur:

        Code:
        [SIZE="2"]
        person
        ------
        id
        first_name
        last_name
        
        
        phone
        -----
        id
        type_fkey => phone_type.id
        country_code
        area_code
        number
        extension
        
        
        phone_type
        ----------
        id
        name
        
        
        person_x_phone
        --------------
        id
        person_fkey => person.id
        phone_fkey  => phone.id
        [/SIZE]
        Wenn ich jetzt alle Personen mit allen ihren Rufnummern und dem Gerätetyp haben will, sieht das so aus:

        Code:
        select
        	`person`.`first_name`,
        	`person`.`last_name`,
        	`phone`.`country_code`,
        	`phone`.`area_code`,
        	`phone`.`number`,
        	`phone`.`extension`,
        	`phone_type`.`name` as `type`
        from `person_x_phone` as `pxp`
        join `person` on `person`.`id` = `pxp`.`person_fkey`
        join `phone` on `phone`.`id` = `pxp`.`phone_fkey`
        join `phone_type` on `phone_type`.`id` = `phone`.`type_fkey`
        Du fängst also am besten mit einer n:m-Tabelle (hier person_x_phone) an, damit du Equi-Joins ausnutzen kannst, die sind nämlich wesentlich schneller und arbeitest dich dann Tabelle für Tabelle durch, wobei du immer nur die Beziehung zwischen zwei Tabellen betrachtest. Das ist auch viel übersichtlicher als das alles in eine Where-Klausel zu quetschen.

        Aus dem Beispiel oben erkennst du also gleich wer wen worüber referenziert. Das Prinzip musst du jetzt nur noch auf deine Tabellen und Spalten anwenden.

        Amica
        [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
        Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
        Super, danke!
        [/COLOR]

        Kommentar


        • #5
          Danke

          Hi Amica,

          danke für die Tipps. Habe ein wenig rumgebastelt, aber erkenne selbst nicht, ob die Serverlast sich verringert hat. Vielleicht fällt dir ja noch was auf, was optimierbar ist (Redundanzen oder sonstige Unsinnigkeiten):


          PHP-Code:
          SELECT 
          manufacturers
          .manufacturers_nameproducts_description.products_namecategories_description.categories_name
          FROM manufacturers_info 
          as mn_x_mid
          join products on products
          .manufacturers_id =  mn_x_mid.manufacturers_id
          join products_description on products_description
          .products_id products.products_id
          join languages on languages
          .languages_id products_description.language_id
          join products_to_categories on products
          .products_id products_to_categories.products_id
          join categories on categories
          .categories_id products_to_categories.categories_id
          join categories_description on categories
          .categories_id categories_description.categories_id
          join manufacturers on products
          .manufacturers_id manufacturers.manufacturers_id 
          Muss ich noch irgendwo einen Index setzen?

          Danke nochmal für deine Hilfe und die schnellen Antworten...

          Kommentar


          • #6
            EXPLAIN SELECT ... und du kannst selbst sehen, wo noch Indizes fehlen.

            Kommentar


            • #7
              ...

              ... und da wo "possible_keys" und "key" übereinstimmen, ist alles gut?

              Danke

              Kommentar


              • #8
                Das muss nicht unbedingt übereinstimmen. Unter possible_keys werden alle möglichen Keys gelistet. Wenn MySQL einen davon benutzt, steht dieser unter key. Sollte dort NULL stehen, ist das gar nicht gut. Achte aber auch auf die Spalte Extras. Dort sollte unter keinen Umständen filesort auftauchen, sondern am besten "Using index".

                Kommentar


                • #9
                  using where....

                  Hi Onemorenerd,

                  habe teilweise auch "Using where" drin. Ist das korrekturbedürftig? Falls ja, wie mache ich das?

                  Danke und lg
                  Zuletzt geändert von Kabbelwasser; 04.01.2010, 14:40. Grund: doof formatiert

                  Kommentar


                  • #10
                    Das ist okay. MySQL :: MySQL 5.1 Referenzhandbuch :: 7.2.1 EXPLAIN-Syntax (Informationen über ein SELECT erhalten)

                    Kommentar


                    • #11
                      [Solved]

                      Danke für eure Hilfe, alles roger!

                      Kommentar

                      Lädt...
                      X