+ Antworten
Ergebnis 1 bis 5 von 5

Thema: mySQL (PHP) - Select in Select optimieren

  1. #1
    TP-Supporter Vitamin-R ist auf einem guten Weg Avatar von Vitamin-R
    Registriert seit
    Sep 2002
    Ort
    Zürich
    Beiträge
    371

    Question mySQL (PHP) - Select in Select optimieren

    Hei
    Für ein momentanes Projekt, befasse ich mich mit SQL, wo ich mich sonst nicht gerade zuhause fühle.

    Ich möchte aus den Tabellen:
    - Student
    - Assignment
    - Module
    - Prerequisite

    jene Module selektieren, welche bestimmte Bedingungen in den anderen Tabellen erfüllen.
    Die DB-Struktur ist teilsvorgegeben und entspricht daher nicht den Normalisierungsregeln, wie die meisten von euch sie wohl kennen oder erwarten würden.

    Zwar habe ich zwei funktionierende Lösungen gefunden, jedoch sind beide extrem langsam.

    Hier die zwei "Lösungen":


    Lösung mit Select in Select
    PHP-Code:
            /** 
             * Gets all Modules which the Student has to visit in the next semester.
             *
             * Possible selection for Term:
             * term6, term8 or term9
             * 
             * Possible selection for ascDesc:
             * ASC or DESC
             * 
             * @param String $acronyme
             * @param String $term The term of the Student
             * @param int $nextSemester
             * @param String $order The order in which the Modules have to be
             * @param String $ascDesc ASC or DESC
             * @return Module[] $obj An array of the Module class objects.
             */
            
    public function getModulesMust($acronyme$term$nextSemester$orderBy$ascDesc){
                try {
                    
    // Actual selection
                    
    $sql "SELECT tempTable.*
                            FROM ( SELECT m.*
                                    FROM   students s
                                      RIGHT JOIN assignment a
                                          ON '" 
    $acronyme ."' = a.student_id
                                              RIGHT JOIN modules m
                                                  ON m.number = a.module_id
                                    WHERE (
                                        a.module_id IS NULL
                                        AND m.type NOT LIKE 'D%'
                                        AND (
                                          a.state = 0
                                          OR
                                          a.state = 3
                                        )
                                      )
                                      OR (
                                        m.type NOT LIKE 'D%'
                                        AND m.type != 'C'
                                        AND m." 
    $term " <= " $nextSemester "
                                      )
                                      OR (
                                        m.type = 'C'
                                        AND m.major_id = s.major_id
                                        AND m." 
    $term " <= " $nextSemester "
                                      )
                                    GROUP BY m." 
    $orderBy "
                                    )
                                AS tempTable,
                                prerequisite p,
                                assignment a,
                                modules m
                            WHERE ( tempTable.number = p.module_id
                                AND p.prerequisite_module_id = m.number
                                AND m.number = a.module_id
                                AND (a.state = 1 OR a.state = 2)
                              )
                              OR(
                                tempTable.prerequisite = 0
                              )
                            GROUP BY tempTable.number
                            ORDER BY tempTable." 
    $orderBy " " $ascDesc "
                    "
    ;
                    
    $stmt DB::getInstance()->query($sql);
                    
    $obj $stmt->fetchALL(PDO::FETCH_CLASS'Module'); 
                    return 
    $obj;
                }
                catch(
    Exception $e){
                    echo 
    $e->getMessage();
                }
            } 
    Lösung mit View:
    PHP-Code:
            /** 
             * Gets all Modules which the Student has to visit in the next semester.
             *
             * Possible selection for Term:
             * term6, term8 or term9
             * 
             * Possible selection for ascDesc:
             * ASC or DESC
             * 
             * @param String $acronyme
             * @param String $term The term of the Student
             * @param int $nextSemester
             * @param String $order The order in which the Modules have to be
             * @param String $ascDesc ASC or DESC
             * @return Module[] $obj An array of the Module class objects.
             */
            
    public function getModulesMust($acronyme$term$nextSemester$orderBy$ascDesc){
                try {
                    
    // Drop View if still exist
                    
    $swlDrop "DROP VIEW IF EXISTS tempModules;";
                    
    DB::getInstance()->query($swlDrop);
                    
                    
                    
    // Create new View
                    
    $sqlView "
                            CREATE VIEW tempModules
                            AS (
                                SELECT
                                       m.type,
                                       m.number,
                                       m.title,
                                       m.prerequisite,
                                       a.student_id,
                                       a.module_id,
                                       a.state,
                                       a.semester
                                FROM
                                    students s
                                        RIGHT JOIN assignment a
                                        ON '" 
    $acronyme "' = a.student_id
                                            RIGHT JOIN modules m
                                            ON m.number = a.module_id
                                WHERE (
                                        a.module_id IS NULL
                                    AND m.type NOT LIKE 'D%'
                                        AND (
                                          a.state = 0
                                          OR
                                          a.state = 3
                                        )
                                )
                                OR (
                                        m.type NOT LIKE 'D%'
                                    AND m.type != 'C'
                                    AND m." 
    $term " <= " $nextSemester "
                                )
                                OR (

                                        m.type = 'C'
                                    AND m.major_id = s.major_id
                                    AND m." 
    $term " <= " $nextSemester "
                                )
                                GROUP BY m.number
                            )
                    "
    ;
                    
    DB::getInstance()->query($sqlView);
                    
                    
    // Actual selection
                    
    $sql "SELECT t.*
                            FROM   tempModules t,
                                   prerequisite p,
                                   assignment a,
                                   modules m
                            WHERE(
                                   t.number = p.module_id
                                AND    p.prerequisite_module_id = m.number
                                AND    m.number = a.module_id
                                AND    (a.state = 1 OR a.state = 2)
                                )
                                OR(
                                       t.prerequisite = 0
                                )
                            GROUP BY t.number
                            ORDER BY t." 
    $orderBy " " $ascDesc "
                    "
    ;
                    
    $stmt DB::getInstance()->query($sql);
                    
    $obj $stmt->fetchALL(PDO::FETCH_CLASS'Module'); 
                    
                    
    // Drop View
                    
    DB::getInstance()->query($swlDrop);
            
                    return 
    $obj;
                }
                catch(
    Exception $e){
                    echo 
    $e->getMessage();
                }
            } 
    Kann mir jemand von euch einen Tipp geben, wie ich (eine der Beiden) Abfrage so optimieren kann, dass mir nicht das Gesicht einschläft, wärend ich auf die Ausgabe warte?


    Gruess

    Vitamin-R
    Geändert von Vitamin-R (19.12.2008 um 18:08 Uhr) Grund: Wurde verschoben. Danke
    Im Zweifelsfalle fragen sie ihren Arzt oder die Suchmaschine ihrer Wahl.

  2. #2
    TP-Special Mod steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User Avatar von steffenk
    Registriert seit
    Feb 2005
    Ort
    Haan / NRW
    Beiträge
    12.869
    Hi,

    trotz dem Code fällt eine Beurteilung schwer, da Eckdaten ja nicht bekannt sind
    * welche DB-Engine wird benutzt
    * welche DB-Klasse wird benutzt

    Die SQL ist mächtig, und wir kennen die Tabellenstruktur nicht. Grossen Einfluss auf Geschwindigkeit sind die Keys und Indizes. Wenn die auf den wichtigen Feldern, die in beziehung stehen, enthalten sind, kann eine Abfrage gut mal um den Faktor 10 beschleunigt werden.

    Gib mal relevantere Eckdaten


    TYPO3 · MySQLDumper · dislabs
    ·
    manche Mühlen mahlen schneller ...
    "Ich habe Rücken"
    Horst Schlämmer


  3. #3
    TP-Supporter Vitamin-R ist auf einem guten Weg Avatar von Vitamin-R
    Registriert seit
    Sep 2002
    Ort
    Zürich
    Beiträge
    371
    Hei steffenk

    Nun ich baue meine DB-Verbindung mittels:
    PHP-Code:
    new PDO("mysql:host=xxx;dbname=xxx"'xxx''xxx');
    setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION); 
    auf.

    die DB-Struktur habe ich mal als jpg angehängt.

    Deinem Text zu Folge könnte es ein Problem sein, dass falsche Datentypen für die PKs verwendet werden?
    Leider wurde bei den Klassen Studentadvisor und Students der Datentyp VCHAR verwendet. Könnte dies ein solches ausbremsen bewirken?
    Angehängte Grafiken  
    Im Zweifelsfalle fragen sie ihren Arzt oder die Suchmaschine ihrer Wahl.

  4. #4
    TP-Supporter Vitamin-R ist auf einem guten Weg Avatar von Vitamin-R
    Registriert seit
    Sep 2002
    Ort
    Zürich
    Beiträge
    371
    Konnte das Problem in einer Nachtschicht doch noch lösen.
    Meine Querry-Versuche, waren einfach total ungeeignet.
    Läuft nun super flüssig ;]

    Das wichtigste in Kürze:
    In meinem SELECT verwende ich nun ein NOT IN.
    Im Zweifelsfalle fragen sie ihren Arzt oder die Suchmaschine ihrer Wahl.

  5. #5
    TP-Special Mod steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User steffenk lebt für das TP und seine User Avatar von steffenk
    Registriert seit
    Feb 2005
    Ort
    Haan / NRW
    Beiträge
    12.869
    Prost


    TYPO3 · MySQLDumper · dislabs
    ·
    manche Mühlen mahlen schneller ...
    "Ich habe Rücken"
    Horst Schlämmer


+ Antworten

Ähnliche Themen

  1. MySQL SELECT
    Von DenisCGN im Forum Traum-Dynamik
    Antworten: 4
    Letzter Beitrag: 16.04.2008, 17:15
  2. Antworten: 2
    Letzter Beitrag: 22.07.2006, 21:57
  3. Frage zu mysql SELECT
    Von dieter99 im Forum Traum-Dynamik
    Antworten: 6
    Letzter Beitrag: 12.06.2006, 20:11
  4. [php&mysql] Select multiple
    Von fyp im Forum Traum-Dynamik
    Antworten: 5
    Letzter Beitrag: 10.05.2005, 14:41
  5. select-box aus mysql-DS
    Von NeTHippie im Forum Traum-Dynamik
    Antworten: 13
    Letzter Beitrag: 30.07.2002, 18:52

Stichworte

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

     

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51