philos Δημοσ. 4 Ιουλίου 2017 Δημοσ. 4 Ιουλίου 2017 Καλημέρα! Λοιπόν, έχουμε τον ακόλουθο κώδικα που υπολογίζει τα points ενός συστήματος "awards". Ο πίνακας award έχει τα awards και ο award_user, τα δεδομένα του σε ποιον χρήση έχει δοθεί, ποιο award. $userpoints = $db->query_first(' SELECT award.*, award_user.*, SUM(award_pointvalue) AS TotalPoints, COUNT(award_user.issue_id) AS TotalAwards FROM ' . TABLE_PREFIX . 'award_user AS award_user LEFT JOIN ' . TABLE_PREFIX . 'award AS award USING (award_id) WHERE award_user.userid = '. intval($userid) . ' AND award.award_active = "1" GROUP BY award_user.userid '); $vbulletin->db->query_write("UPDATE " . TABLE_PREFIX . "user SET sc_awards_number = ". intval($userpoints['TotalAwards']) .", sc_awards_points = ". intval($userpoints['TotalPoints']) ." WHERE userid = " . intval($userid) . ""); Το θέμα: ο παραπάνω κώδικας, μπορεί να θέλω να τρέξει, ας πούμε για κάποιες χιλιάδες userids σε μια while ( ; ) * Έχετε να προτείνετε κάποια τροποποίηση στον κώδικα χάρην απόδοσης; Κάτι που έχω κατά νου: - Ίσως το $userpoints query μπορεί να ενσωματωθεί ως υποερώτημα στην UPDATE; Αν γίνεται κάτι τέτοιο, ποια η σύνταξη; - Ακόμα πιο προχωριμένα: μπορεί να ενσωματωθεί ως υποερώτημα στην UPDATE + να μπει ένα "WHERE userid IN (); * Βασικά για να σας δώσω να καταλάβετε τι θέλω να κάνω: θέλω για συγκεκριμένα award_ids να ενημερώσω το sc_awards_number και sc_awards_points του πίνακα user, για τους χρήστες που έχουν το/τα συγκεκριμένα award_id(s). Αυτή τη στιγμή, τραβάω τους χρήστες από το award_user και σε μια php while τρέχω τον από πάνω κώδικα. Απλά όταν ένα ή περισσότερα awards έχουν 1000 δες χρήστες, νομίζω η προσεγγισή μου δεν είναι και η καλύτερη. Κάθε βοήθεια ευπρόσδεκτη.
leonidas_fs Δημοσ. 5 Ιουλίου 2017 Δημοσ. 5 Ιουλίου 2017 Προσωπικά εγω θα έκανα ενα schedule task (ή ενα cron task αν είσαι σε Linux), οπου 1 ή 2 φορές την μέρα (αναλόγως τις ανάγκες σου) θα έκανε update τα sc_awards_number και sc_awards_points στην database σου. Με αυτό τον τρόπο θα μειώσεις το MySQL ερώτημα σου, αφού το update θα γίνεται με το schedule task και ουσιαστικά στην PHP σου θα κάνεις μονο ενα select.
philos Δημοσ. 5 Ιουλίου 2017 Μέλος Δημοσ. 5 Ιουλίου 2017 Βασικά το σύστημα λειτουργεί ως εξής: κάθε φορά που δίνεται ένα award σε κάποιον user (χειροκίνητη λειτουργία του διαχειριστή), για τον συγκεκριμένο χρήστη, ενημερώνονται τα points του. Όμως αν ο admin αλλάξει τα points ενός award, θέλουμε να υπάρχει η παραπάνω δυνατότητα για συγκεκριμένα awardids, να γίνονται update τα points όσων χρηστών τα έχουν. Πρόκειται στην ουσία για manual λειτουργία του admin και προτιμάμε να μη τη βάλουμε σε scheduled task. Μπορούμε να το κάνουμε το εργαλείο να προσεσσάρει χρήστες σε παρτίδες κατά το run του script (= νέα σελίδα ανά Χ αριθμό χρηστών), απλά σκεφτόμουν μήπως υπάρχει κάποιος τρόπος με αποκλειστική χρήση ερωτήματος και υποερωτημάτων σε αυτό, να γίνει γρήγορα η διαδικασία ή να βελτιωθεί ο υπάρχων κώδικας, τουλάχιστον.
lionheart82 Δημοσ. 12 Ιουλίου 2017 Δημοσ. 12 Ιουλίου 2017 Καλησπέρα, θα συμφωνήσω με το scheduled task. Εννοείται πως εάν θέλουμε να γίνουν οι αλλαγές από τον admin μπορεί να τρέξει το script ή κάποιο υπό-script χειροκίνητα. Για το query θα μπορούσε να γίνει η ενημέρωση με ένα query μπορείς να δεις στο google με το search term “mysql update from select join” παραδείγματα. Το θέμα για το γρηγορότερα βέβαια έχει να κάνει με πολλούς παράγοντες. ΠΧ τι επίπεδο κανονικοποίησης έχει η βάση; Τι συσχετίσεις; Τι indexes; Στην τελική ανάλυση θα πρέπει να γίνουν tests και να βρεθεί ο γρηγορότερος χρόνος εκτέλεσης για το εκάστοτε query ώστε να καταλήξεις κάπου και αυτό δεν γίνεται μέσα από το forum
warlock9_0 Δημοσ. 13 Ιουλίου 2017 Δημοσ. 13 Ιουλίου 2017 κάτι τέτοιο πολύ πρόχειρα δε σου κάνει? χωρίς while, με in για να βάλεις τα id που θέλεις update user set sc_awards_number = tmp.totalawards, sc_awards_points = tmp.totalpoints from user inner join ( SELECT award.*, award_user.*, SUM(award_pointvalue) AS TotalPoints, COUNT(award_user.issue_id) AS TotalAwards FROM award_user AS award_user LEFT JOIN award AS award USING (award_id) WHERE award_user.userid in ( ta userid pou 8es) AND award.award_active = "1" GROUP BY award_user.userid ) tmp on user.userid = tmp.userid
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα