Seite 1 von 1

Hilfe beim "Subselect sparen"

Verfasst: 28.03.2013 23:16
von BNa
Hallo Gemeinde,

ich brauch mal die Hilfe eines SQL Sachkundigen, da ich hier an die Grenze meines SQL Grundverständnisses stosse.

Knackpunkt ist das vorab als Variable $sql_arp definierte Subselect. Es erzeugt zuviel Last.
Ich habe schon vieles getestet und probiert. Alle möglichen JOIN's und so fort, find aber die Lösung nicht.
Alle von mir versuchten alternativen Abfragen bringen nicht das Ergebnis, wie es die vorliegende Abfrage bringt.

Code: Alles auswählen

// Knackpunkt
$sql_arp = "(SELECT MAX(post_time) FROM " . POSTS_TABLE . " WHERE u.user_id = poster_id)";
$sql_ary = array(
    'SELECT'    => "u.username AS u_name, u.user_email, $sql_arp AS posttime, u.user_type, u.user_id, u.user_posts, u.user_colour, u.user_avatar, u.user_avatar_type, u.user_avatar_width, u.user_avatar_height, u.user_lastvisit, u.test_0, u.test_1, u.test_2, p.post_subject, p.forum_id, p.post_id",
    'FROM'      => array(
        USERS_TABLE    => "u",
        ),
    'LEFT_JOIN'  => array(
        array(
            'FROM' => array(POSTS_TABLE => 'p'),
            'ON'   => "$sql_arp = p.post_time",
        )
    ),
    'WHERE'        => "UNIX_TIMESTAMP( ) - $sql_arp > $days *24 *3600
                    AND u.user_posts != 0",                    
    'ORDER_BY'     => "$sql_arp DESC"
);
$sql = $db->sql_build_query('SELECT', $sql_ary); 
Eventuell würde ja eine Aufsplittung in 2 Abfragen helfen!? Aber auch da bin ich nicht weiter gekommen.

Re: Hilfe beim "Subselect sparen"

Verfasst: 29.03.2013 07:30
von Miriam
Check das ->

Code: Alles auswählen

// Knackpunkt
// $sql_arp = "(SELECT MAX(post_time) FROM " . POSTS_TABLE . " WHERE u.user_id = poster_id)";
$sql_ary = array(
    'SELECT'    => "p.post_subject, p.forum_id, p.post_id, u.username AS u_name, u.user_email, p.post_time AS posttime, u.user_type, u.user_id, u.user_posts, u.user_colour, u.user_avatar, u.user_avatar_type, u.user_avatar_width, u.user_avatar_height, u.user_lastvisit, u.test_0, u.test_1, u.test_2",
    'FROM'    => array(
        POSTS_TABLE    => "p",
        ),
    'LEFT_JOIN'    => array(
        array(
            'FROM' => array(USERS_TABLE => 'u'),
            'ON'    => "u.user_id = p.poster_id",
        )
    ),
    'WHERE'            => time() . " - p.post_time > $days *24 *3600
                    AND p.post_time = u.user_lastpost_time
                    AND u.user_posts <> 0"
);
$sql = $db->sql_build_query('SELECT', $sql_ary);  

Re: Hilfe beim "Subselect sparen"

Verfasst: 29.03.2013 18:06
von BNa
Danke. Ich werds ausprobieren..

Re: Hilfe beim "Subselect sparen"

Verfasst: 29.03.2013 22:17
von BNa
Leider dasselbe Ergebnis, wie in den schon angedeuteten eigenen Test.
Es werden nur 29 User ausgegeben, anstatt 36, wie bei meinem unperformanten Code.
Ist echt zum Haare raufen, vielleicht hat noch jemand einen Ansatz.

Re: Hilfe beim "Subselect sparen"

Verfasst: 29.03.2013 22:27
von Miriam
Welche User fehlen denn?

Re: Hilfe beim "Subselect sparen"

Verfasst: 29.03.2013 22:34
von BNa
Habs oben nochmal korrigiert. Es sollten normal 36 sein.

Der Code war ja schon mal OK. Das Problem(!) kam eigentlich erst auf, als mir auffiel, das user_lastpost_time > p.post_time = u.user_lastpost_time auch eine PM sein kann. Schreib ich nämlich als letztes eine PM, ohne noch einen Beitrag zu schreiben, hat es auf der Liste nichts zu suchen :wink:
Deswegen der Ansatz der (MAX) post_time as post_time, was dann auch wunderbar funktioniert hatte, nur halt zu lastig.

Guck, so soll es sein
http://www.4seven.de/forum/6test/memberlist_date.php

Memberlist im Vergleich
http://www.4seven.de/forum/6test/memberlist.php

Und jeder von mir bisher versuchter Spar Code bringt nur 29 User.

Re: Hilfe beim "Subselect sparen"

Verfasst: 30.03.2013 01:20
von BNa
Danke für die Inspiration. Ich werds noch etwas austesten aber es sieht gut aus.
Die Engine ist jetzt schnell, da machts richtig Spaß weiterzumachen.

Der Code sieht jetzt so aus:

Code: Alles auswählen

$sql_ary = array(
    'SELECT'    => "max(post_time) as posttime, u.username, u.user_email, u.user_type, u.user_id, u.user_posts, u.user_colour, u.user_avatar, u.user_avatar_type, u.user_avatar_width, u.user_avatar_height, u.user_lastvisit, u.test_0, u.test_1, u.test_2, p.post_subject, p.forum_id, p.post_id",
    'FROM'      => array(
        USERS_TABLE         => "u",
        POSTS_TABLE         => "p"
        ),
    'WHERE'    =>   time() . " - post_time > $days *24 *3600
                    AND user_id = poster_id    
                    AND user_posts <> 0
                    AND user_id <> " . ANONYMOUS,
    'GROUP_BY'  => "user_id",                    
    'ORDER_BY'  => "max(post_time) DESC"
);
$sql = $db->sql_build_query('SELECT', $sql_ary);