Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Υπάρχει πρόβλημα με το ακόλουθο query σε ένα script που δείχνει τα TOP 5 βαθμολογημένα θέματα της εβδομάδας. Συγκεκριμένα, όταν τρέχει το query, επιστρέφεται το ακόλουθο error:

SELECT post.postid, post.userid AS postuserid, post.username AS postusername, thread.title AS title, thread.forumid, thread.threadid, sum1, thread.replycount, thread.views, thread.dateline
FROM post AS post INNER JOIN
(
SELECT sc_thumbs_post.postid, COUNT(sc_thumbs_post.thumb) AS sum1
FROM sc_thumbs_post AS sc_thumbs_post
LEFT JOIN thread AS thread ON (thread.firstpostid = sc_thumbs_post.postid)
WHERE YEARWEEK(from_unixtime(sc_thumbs_post.dateline), 0) = YEARWEEK(CURRENT_DATE, 0) AND (sc_thumbs_post.thumb = 1)
GROUP BY sc_thumbs_post.postid
) tmp ON post.postid = tmp.postid
LEFT JOIN thread AS thread ON (thread.firstpostid = tmp.postid)
LEFT JOIN forum AS forum ON (thread.forumid = forum.forumid)
WHERE thread.threadid IS NOT NULL AND forum.forumid NOT IN ('4', '73', '99', '76', '78', '77', '0')
GROUP BY thread.threadid
ORDER BY sum1 DESC, thread.lastpost DESC
LIMIT 5;


MySQL Error   : MySQL server has gone away
Error Number  : 2006

 
Τι μπορεί να φταίει; Η πλάκα είναι ότι στο localhost μου παίζει κανονικά το query, ενώ σε έναν κανονικό server που δοκιμάζεται, βγαίνει το παραπάνω.

Που είναι το πρόβλημά του; Μήπως φταίνε τα limits του server; Διαφορετικά, πως μπορώ να το βελτιστοποιήσω/διορθώσω; :-)

Δημοσ.

Επειδη μου εκανε και μενα εντυπωση, μετα απο ενα γρηγορο ψαξιμο παιζει να

*εχει γινει καποιο λογικο λαθος στον κωδικα και να τρεχεις ενα query αφου εχει κλεισει η συνδεση με τον σερβερ

*εχεις βαλει καπου καποια επιλογη για timeout στον client

*το reconnect της mySQL ειναι 0

 

πιο αναλυτικα τσεκαρε Link.png Site: εδω

Δημοσ.

Το παράξενο είναι ότι δε βλέπω κάποιο λάθος στον κώδικα. Ο πελάτης περιγράφει το εξής (όταν ενεργοποιεί το module που τρέχει το παραπάνω query):

each times the head page loading and loading after getting databse error
after restart of mysql website running again

 

Τέλος, σε άλλον έναν server που δοκιμάστηκε, βγάζει error:

getting error
PDOException: SQLSTATE[08004] [1040] Too many connections

 

 

Από αυτά τι συμπέρασμα βγάζουμε;

 

Μήπως φταίει το query το οποίο είναι κάπως βαρύ ή κάτι άλλο μέσα στο script μου (php) ;

Πάντως δεν είναι φυσικό να τρέχει κανονικά το site με όλα τα άλλα scripts που μπορεί να έχει εγκαταστήσει και να κολλάει στο δικό μου (δλδ αν τίθεται θέμα limitation στις ρυθμίσεις του server). :fear:

Δημοσ.

Απο αυτα που μου λες ή ειναι βαρυ το query σου ή ανοιγεις πολλες συνδεσεις κ δεν τις κλεινεις? Επειδη σου πεταει "Too many connections" το λεω. 

 

Ειναι λιγο παλουκι αμα μπλεξεις με querys. Μια ανεπισημη τεχνικη ειναι να googlαρεις καθε φορα το error που σου βγαζει για να βλεπεις λεπτομεριες. 

Δημοσ.

Λογικό και εγώ αν ήμουν mysql server θα αρνιόμουν πεισματικά να το τρέξω:Ρ 

Δημοσ.

Λογικό και εγώ αν ήμουν mysql server θα αρνιόμουν πεισματικά να το τρέξω:Ρ 

 

Υπερβολικό σε βρίσκω! Έχω δει και μεγαλύτερες (και βαρύτερες!)

Με "συνετό" normalization και επαρκή, έξυπνα indexes θα την έτρεχες μια χαρά.

 

@philos

Επειδή η απόδοση μίας query εξαρτάται πρωτίστως από άλλα πράγματα, και δευτερευόντως από τον τρόπο που τη γράφεις, δεν ποστάρεις τη δομή της βάσης σου και τη λογική πίσω από τη συγκεκριμένη query;

...ώστε να μπορέσουμε να σε "ανακρίνουμε" περαιτέρω... :-D

Δημοσ.

Λοιπόν, σας ποστάρω τη δομή των πινάκων που χρησιμοποιούνται στο query. Θα χαρώ πολύ να με βοηθήσετε!

Όπως είπα στο localhost μου δουλεύει μια χαρά, σε server άλλον όμως όχι.

 

::: Πίνακας post ::: (μηνύματα ενός forum)

postid (Autoincrement)

userid (το id του χρήστη που έκανε το post)

username

dateline (η σφραγίδα χρόνου που έγινε το post)

 

::: Πίνακας thread::: (θέματα ενός forum)

threadid (Autoincrement)

firstpostid (το postid του πρώτου μηνύματος του thread - σχετίζεται με τον πίνακα post)

title (τίτλος του thread)

forumid (id της κατηγορίας forum που ανήκει το thread)

replycount (αριθμός απαντήσεων στο thread)

views

dateline ((η σφραγίδα χρόνου που δημιουργήθηκε το θέμα)

 

::: Πίνακας sc_thumbs_post :::: (θετικές/αρνητικές ψήφοι στα posts του forum)

id (Autoincrement)

postid

thumb (πέρνει τιμές 1 ή -1)

dateline (η σφραγίδα χρόνου που δόθηκε η ψήφος thumbsup/down)

 

Με το συγκεκριμένο query θέλω να εξάγω τα top 5 ψηφισμένα θετικά (thumb = 1 ) threads της εβδομάδας (προσοχή, threads, όχι posts ως κανονικές απαντήσεις! , οπότε θέλουμε το query να τσεκάρει μόνο τα firstpostids, να αρθροίζει τις θετικές ψήφους και να τις κάνει sort by αυτές = TOP 5 ).

 

Αν έχετε υπόψιν σας κάποιο ποιο αποδοτικό τρόπο να βγάλω τα αποτελέσματα, θα χαρώ να μου πείτε. :)

Για όποια άλλη ερώτηση είμαι εδώ!

Δημοσ.

Πήγαινε στο phpmyadmin στον server (υποθέτω ότι υπάρχει, αλλιώς τρέξε με άλλο τρόπο το query, αν δεν ξέρεις πες) το εξής:

SHOW VARIABLES

Αυτό θα σου επιστρέψει μερικές μεταβλητές, θα ήθελα να μου πεις τις τιμές των μεταβλητών max_allowed_packet και wait_timeout.

Δημοσ.

Πήγαινε στο phpmyadmin στον server (υποθέτω ότι υπάρχει, αλλιώς τρέξε με άλλο τρόπο το query, αν δεν ξέρεις πες) το εξής:

SHOW VARIABLES

Αυτό θα σου επιστρέψει μερικές μεταβλητές, θα ήθελα να μου πεις τις τιμές των μεταβλητών max_allowed_packet και wait_timeout.

Δεν γνωρίζω τις παραπάνω τιμές καθώς ο server στον οποίο δοκιμάζεται και δεν τρέχει σωστά, δεν είναι δικός μου. Μπορώ ωστόσο να ρωτήσω και να σας πω.

 

Πάντως δοκίμασα να μειώσω το max_allowed_packet ακόμα και σε 10K στο localhost μου και πάλι δεν εμφάνισε πρόβλημα (σε μένα δηλαδή).

Σας παραθέτω όλο το script (δεν είναι μεγάλο) :

<?php
  $final_excludearray = $adv_canviewforums;
  $excludeids_string = $mod_options['sc_top_thumbup_threads_exforums'];
  $excludeids_array = explode(',', $excludeids_string);
  if (!empty($excludeids_array))
  {
     foreach ($excludeids_array AS $exforumid)
     {
       $final_excludearray[] = intval($exforumid);
     }
  }                                                                   
        $top_threads_up = $db->query_read("
            SELECT post.postid, post.userid AS postuserid, post.username AS postusername, thread.title AS title, thread.forumid, thread.threadid, sum1, thread.replycount, thread.views, thread.dateline
            FROM " . TABLE_PREFIX . "post AS post INNER JOIN
            (
                SELECT sc_thumbs_post.postid, COUNT(sc_thumbs_post.thumb) AS sum1
                FROM " . TABLE_PREFIX . "sc_thumbs_post AS sc_thumbs_post
                LEFT JOIN " . TABLE_PREFIX . "thread AS thread ON (thread.firstpostid = sc_thumbs_post.postid)
                WHERE YEARWEEK(from_unixtime(sc_thumbs_post.dateline), 0) = YEARWEEK(CURRENT_DATE, 0) AND (sc_thumbs_post.thumb = 1)
                GROUP BY sc_thumbs_post.postid
            ) tmp ON post.postid = tmp.postid
            LEFT JOIN " . TABLE_PREFIX . "thread AS thread ON (thread.firstpostid = tmp.postid)
            LEFT JOIN " . TABLE_PREFIX . "forum AS forum ON (thread.forumid = forum.forumid)
            WHERE thread.threadid IS NOT NULL AND forum.forumid NOT IN ('" . implode("', '", $final_excludearray) . "')
            GROUP BY thread.threadid
            ORDER BY sum1 DESC, thread.lastpost DESC
            LIMIT ". intval($mod_options['sc_top_thumbup_threads_limit']) ."
          ");        
        
        $topcount = 1;
        while ($thread = $db->fetch_array($top_threads_up))
        {
            $date = vbdate($vbulletin->options['dateformat'], $thread['dateline'], $doyestoday= true);
            $time = vbdate($vbulletin->options['timeformat'], $thread['dateline']);
          $thread['datetime'] = $date . ' - ' . $time;        
          $templater = vB_Template::create('adv_portal_weektop_threads_bit');
            $templater->register('thread', $thread);
            $templater->register('topcount', $topcount);
          $top_bits .= $templater->render();  
          $topcount++;
        }
       $db->free_result($top_threads_up);

$templater = vB_Template::create('adv_portal_weektop_threads');
$templater->register('mod_options', $mod_options);
$templater->register('top_bits', $top_bits);
$home["$mods[modid]"]['content'] = $templater->render();

?>
Δημοσ.
::: Πίνακας post ::: (μηνύματα ενός forum)

postid (Autoincrement)

userid (το id του χρήστη που έκανε το post)

username

dateline (η σφραγίδα χρόνου που έγινε το post)

 

::: Πίνακας thread::: (θέματα ενός forum)

threadid (Autoincrement)

firstpostid (το postid του πρώτου μηνύματος του thread - σχετίζεται με τον πίνακα post)

title (τίτλος του thread)

forumid (id της κατηγορίας forum που ανήκει το thread)

replycount (αριθμός απαντήσεων στο thread)

views

dateline ((η σφραγίδα χρόνου που δημιουργήθηκε το θέμα)

 

::: Πίνακας sc_thumbs_post :::: (θετικές/αρνητικές ψήφοι στα posts του forum)

id (Autoincrement)

postid

thumb (πέρνει τιμές 1 ή -1)

dateline (η σφραγίδα χρόνου που δόθηκε η ψήφος thumbsup/down)

 

Εκτός του ότι λείπει ο forum, κάτι άλλο δεν μου πάει καλά.

Πως συνδέεται κάθε post με το thread στο οποίο ανήκει;

Δημοσ.

Εκτός του ότι λείπει ο forum, κάτι άλλο δεν μου πάει καλά.

Πως συνδέεται κάθε post με το thread στο οποίο ανήκει;

Τον forum δε τον έβαλα γιατί πιστεύω δεν έχει και πολύ νόημα:

forumid (autoincrement)

title

κτλ

 

Α, συγγνώμη, ο πίνακας post έχει μεταξύ των άλλων που παρέλειψα και column threadid.

Δημοσ.

Με το συγκεκριμένο query θέλω να εξάγω τα top 5 ψηφισμένα θετικά (thumb = 1 ) threads της εβδομάδας (προσοχή, threads, όχι posts ως κανονικές απαντήσεις! , οπότε θέλουμε το query να τσεκάρει μόνο τα firstpostids, να αρθροίζει τις θετικές ψήφους και να τις κάνει sort by αυτές = TOP 5 ).

 

1) Οποτε θελεις απο τον posts μόνο τις γραμμές που αντιστοιχούν σε thread.firstpostid;

2) Και μόνο αυτά "της εβδομάδας"; Και με αυτό τι εννοείς, των τελευταίων 7 ημερών ή πχ από την τελευταία Δευτέρα έως σήμερα;

Δημοσ.

1) Οποτε θελεις απο τον posts μόνο τις γραμμές που αντιστοιχούν σε thread.firstpostid;

2) Και μόνο αυτά "της εβδομάδας"; Και με αυτό τι εννοείς, των τελευταίων 7 ημερών ή πχ από την τελευταία Δευτέρα έως σήμερα;

1. Ναι :-)

2. Από την Κυριακή μέχρι σήμερα. Δηλαδή Κυριακή στις 12:01πμ τα αποτελέσματα θα είναι "ελάχιστα" προς μηδαμινά. και όσο περνάνε οι μέρες αυξάνονται (λογικά).

 

Γενικά το query που έχω γράψει μου εμφανίζει σωστά τα αποτελέσματα να ξέρετε. Έχεις να προτείνεις κάποια βελτιωμένη έκδοση;

Δημοσ.

Που είναι το πρόβλημά του; Μήπως φταίνε τα limits του server; Διαφορετικά, πως μπορώ να το βελτιστοποιήσω/διορθώσω; :-)

 

Δεν φαίνεται εκ πρώτης όψεως να έχει σχέση με την περίπτωσή σου, αλλά στο παρελθόν είχα συναντήσει αυτό το πρόβλημα και έφταιγε το max allowed packet, οπότε στη θέση σου θα το τσέκαρα. Κάτι άλλο το οποίο είναι μεν wild guess αλλά έχει μια κάποια λογική είναι πως το query σου κάνει 10 χρόνια για να τρέξει και στο ενδιάμεσο γίνεται TCP timeout (βέβαια αν ήταν έτσι τότε η εφαρμογή σου θα είχε πρόβλημα έτσι κι αλλιώς λόγω καθυστέρησης, οπότε ούτε αυτό ακούγεται πολύ πειστικό).

 

Τέλος δες κι εδώ και προσπάθησε να αποκλείσεις τα ενδεχόμενα ένα ένα.

Δημοσ.

1. Ναι :-)

2. Από την Κυριακή μέχρι σήμερα. Δηλαδή Κυριακή στις 12:01πμ τα αποτελέσματα θα είναι "ελάχιστα" προς μηδαμινά. και όσο περνάνε οι μέρες αυξάνονται (λογικά).

 

Γενικά το query που έχω γράψει μου εμφανίζει σωστά τα αποτελέσματα να ξέρετε. Έχεις να προτείνεις κάποια βελτιωμένη έκδοση;

 

Για να πω την αλήθεια, δεν διάβασα αναλυτικά το query σου. Μου είναι πολύ πιο εύκολο, έχοντας τη δομή της βάσης και ξέροντας τι θέλεις να κάνεις, να το παράγω από την αρχή. Λοιπόν, έχουμε και λέμε:

 

Το παρακάτω σου δίνει το top 5 των posts που εμφανίζονται στο firstpostid, σύμφωνα με τα κριτήριά σου (τα πήρα αυτούσια από τη δική σου query):

select postid,count(thumb) as sum1 from sc_thumbs_post
where postid in (
  select firstpostid from thread 
  where forumid not in ('4', '73', '99', '76', '78', '77', '0')
  )
and YEARWEEK(from_unixtime(sc_thumbs_post.dateline), 0) = YEARWEEK(CURRENT_DATE, 0) and thumb=1
group by postid
order by count(thumb) desc
limit 5

Τυπικά, η nested query ήθελε ένα distinct, αλλά εφόσον η συσχέτιση firstpostid είναι 1:1, δεν χρειάζεσαι το overhead.

Επειδή δεν την έχω δοκιμάσει, καλύτερα να τη δοκιμάσεις μόνη της σε ένα phpmyadmin πριν πας παρακάτω.

 

Επομένως, η query σου γίνεται:

SELECT 
  post.postid, post.userid AS postuserid, post.username AS postusername, 
  thread.title AS title, thread.forumid, thread.threadid, sum1, thread.replycount, 
  thread.views, thread.dateline
FROM post AS post INNER JOIN ( /* το παραπάνω */ ) tmp ON post.postid = tmp.postid
INNER JOIN thread AS thread ON (thread.firstpostid = tmp.postid)
ORDER BY sum1 DESC, thread.lastpost DESC

Επίσης αδοκίμαστη, αν σου βγάζει λάθος το βλέπουμε.

 

Επιδέχεται κι άλλες βελτιώσεις. Για παράδειγμα, η πρώτη query θα μπορούσε να γίνει from sc_thumbs_post join thread αντί για in ώστε να μη χρειαστεί απ' έξω να κάνεις άλλο ένα join thread. Αλλά μπορεί να τη χρειάζεσαι έτσι, για να τη χρησιμοποιήσεις και κάπου αλλού.

 

Τέλος, υποθέτω ότι έχεις ορίσει τα απαραίτητα indexes.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...