Είναι βαρύ ένα query σαν αυτό;

Συζητήσεις για την βάση δεδομένων MySQL και το phpMyAdmin

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
Άβαταρ μέλους
philos
Δημοσιεύσεις: 264
Εγγραφή: 30 Αύγ 2007 23:32

Είναι βαρύ ένα query σαν αυτό;

Δημοσίευση από philos » 11 Ιαν 2013 15:28

Θα ήθελα να ρωτήσω το εξής σχετικά με το κατά πόσο είναι "επίπονο" για τον server ένα query σαν το ακόλουθο, το οποίο όπως θα διαπιστώσετε θα τρέχει συχνά, κι αν υπάρχει κάποιος soft τρόπος να πετύχω αυτό που θέλω.

Λοιπόν, έχουμε τον πίνακα groupmembership, ο οποίος περιέχει τα δεδομένα που αφορούν τη συμμετοχή των users (userid) σε ομάδες συζητήσεων (groupid). Η δομή του είναι η ακόλουθη:
::groupmembership::
userid
groupid
dateline (σφραγίδα χρόνου που το μέλος γράφτηκε στην ομάδα)
type (λαμβάνει τιμές member, moderated, invited)

Θέλω να φτιάξω ένα σύστημα ειδοποιήσεων για νέα στοιχεία στην κάθε ομάδα. Έτσι σκέφτηκα στον παραπάνω πίνακα, να προσθέσω δύο επιπλέον columns:
α) το notifications_count (INT(5)) (ο counter των ειδοποιήσεων)
β) και το notifications_on (BOOL) default '1' [το on/off πεδίο, όταν κάποιος χρήστης (userid) κλείνει τις ειδοποιήσεις για μια ομάδα (groupid) λαμβάνει τιμή 0].

Οπότε, όταν γίνεται κάποιο νέο στοιχείο στην τάδε ομάδα, θα τρέχει ένα query που θα κάνει notifications_count+1 σε όσες rows του πίνακα έχουν groupid = τάδε ΚΑΙ notifications_on=1 ΚΑΙ type='member'.

Αυτός δεν είναι ο καλύτερος τρόπος να κάνω αυτό που θέλω;
Αν υποθέσουμε ότι μια ομάδα έχει 20.000 μέλη (δλδ σε ένα groupid αντιστοιχούν 20.000 userids), μήπως το παραπάνω query θα γονατίζει τον server; Όπως είπα θα τρέχει πολύ τακτικά. :idea:

Άβαταρ μέλους
_tasos
Δημοσιεύσεις: 116
Εγγραφή: 03 Μάιος 2007 15:06
Επικοινωνία:

Είναι βαρύ ένα query σαν αυτό;

Δημοσίευση από _tasos » 11 Ιαν 2013 20:39

Όταν λες θα τρέχει πολύ συχνά; Θα τρέχει π.χ. κάθε 5 λεπτά ή θα τρέχει όταν κάποιος user θα κοιτάει να δει αν έχει notifications;

Κάποιες ιδέες για το performance στο query αυτό:
Βάλε ένα index πάνω στο userid (αν δεν έχεις ήδη), για να έχεις γρηγορότερα queries.
Αν άλλαζες το πεδίο member σε int αντί για varchar θα βελτίωνες λίγο την ταχύτητα, τα φίλτρα σε varchar πεδία είναι πιο βαριά.
Θα μπορούσες να τρέχεις το SELECT χωρίς να κάνεις lock τον πίνακα. Δες εδώ http://stackoverflow.com/questions/9176 ... g-in-mysql για το πως θα μπορούσε να γίνει.

Μία άλλη προσέγγιση που σκεφτόμουν είναι να κρατάς για κάθε group το τελευταίο timestamp για το οποίο γεννήθηκε ένα notification και μετά να έχεις για κάθε user το timestamp από την τελευταία φορά που ενημερώθηκε για τυχόν notifications. Έτσι όμως, δεν ξέρεις πόσα είναι τα notifications του user για το group, αλλά θα είναι πιο ελαφρύ σαν query.

Άβαταρ μέλους
cordis
Administrator, [F|H]ounder, [C|S]EO
Δημοσιεύσεις: 27630
Εγγραφή: 09 Οκτ 1999 03:00
Τοποθεσία: Greece
Επικοινωνία:

Είναι βαρύ ένα query σαν αυτό;

Δημοσίευση από cordis » 12 Ιαν 2013 17:58

φτιάχνεις έναν πίνακα notification και τρέχεις ένα cron που τον διαβάζει συνέχεια.

με το που βάζεις μια εγγραφή εκεί τα μέλη της ομάδας παίρνουν μια ειδοποίηση και η γραμμή διαγράφετε.
Δεν απαντάω σε προσωπικά μηνύματα με ερωτήσεις που καλύπτονται από τις ενότητες του forum. Για ο,τι άλλο είμαι εδώ για εσάς.
- follow me @twitter

Άβαταρ μέλους
philos
Δημοσιεύσεις: 264
Εγγραφή: 30 Αύγ 2007 23:32

Είναι βαρύ ένα query σαν αυτό;

Δημοσίευση από philos » 13 Ιαν 2013 12:07

_tasos έγραψε:Όταν λες θα τρέχει πολύ συχνά; Θα τρέχει π.χ. κάθε 5 λεπτά ή θα τρέχει όταν κάποιος user θα κοιτάει να δει αν έχει notifications;

Κάποιες ιδέες για το performance στο query αυτό:
Βάλε ένα index πάνω στο userid (αν δεν έχεις ήδη), για να έχεις γρηγορότερα queries.
Αν άλλαζες το πεδίο member σε int αντί για varchar θα βελτίωνες λίγο την ταχύτητα, τα φίλτρα σε varchar πεδία είναι πιο βαριά.
Θα μπορούσες να τρέχεις το SELECT χωρίς να κάνεις lock τον πίνακα. Δες εδώ http://stackoverflow.com/questions/9176 ... g-in-mysql για το πως θα μπορούσε να γίνει.

Μία άλλη προσέγγιση που σκεφτόμουν είναι να κρατάς για κάθε group το τελευταίο timestamp για το οποίο γεννήθηκε ένα notification και μετά να έχεις για κάθε user το timestamp από την τελευταία φορά που ενημερώθηκε για τυχόν notifications. Έτσι όμως, δεν ξέρεις πόσα είναι τα notifications του user για το group, αλλά θα είναι πιο ελαφρύ σαν query.
Θα τρέχει κάθε 10 λεπτά ξέρω 'γω. Αν και τώρα που το σκέφτομαι, θα έχω από default κλειστές τις ειδοποιήσεις για νέα μηνύματα στο forum της ομάδας, οπότε μάλλον δεν θα τρέχει και πολύ συχνά (θα τρέχει από default για άλλα στοιχεία της ομάδας).

Δεν πολυ κατάλαβα την ιδέα με το timestamp!
cordis έγραψε:φτιάχνεις έναν πίνακα notification και τρέχεις ένα cron που τον διαβάζει συνέχεια.

με το που βάζεις μια εγγραφή εκεί τα μέλη της ομάδας παίρνουν μια ειδοποίηση και η γραμμή διαγράφετε.
Για να σταλλεί όμως η ειδοποίηση θα πρέπει να "πάρω" τα userids από τον πίνακα groupmembership, οπότε μήπως τελικά η καλύτερη λύση είναι να χρησιμοποιήσω τον πίνακα groupmembership;
Η ειδοποίηση λαμβάνεται με ένα απλό query που απλώς παίρνει την τιμή του notifications_count για userid = X, από εκεί και ύστερα όλα τα άλλα τα κάνει το σύστημα (εμφανίζει τον αριθμό των ειδοποιήσεων και στέλνει τον χρήστη σε μια σελίδα με τα τελευταία στοιχεία της ομάδας, όπου και το notifications_count μηδενίζεται).
Δεν με ενδιαφέρει η ειδοποίηση να έχει συγκεκριμένες πληροφορίες (πχ για ποιο στοιχείο δημιουργήθηκε η ειδοποίηση). Αρκεί να στέλνω τον χρήστη στη σελίδα με τα τελεταία στοιχεία. :D

Άβαταρ μέλους
_tasos
Δημοσιεύσεις: 116
Εγγραφή: 03 Μάιος 2007 15:06
Επικοινωνία:

Είναι βαρύ ένα query σαν αυτό;

Δημοσίευση από _tasos » 13 Ιαν 2013 12:14

philos έγραψε: Δεν πολυ κατάλαβα την ιδέα με το timestamp!
Θα έχεις έναν πίνακα με εγγραφές για κάθε group. Σε κάθε εγγραφή θα έχεις την ημερομηνία της τελευταίας ενημέρωσης. Θα κρατάς επίσης για κάθε user πότε ήταν η τελευταία χρονική στιγμή που έκανε check για ενημέρωση.
Οπότε ένας χρήστης θα έχει ενημέρωση από τα groups που η δικιά τους ημερομηνία ενημέρωσης είναι μεγαλύτερη από αυτή του χρήστη.

Π.χ.

groupid, lastupdate
1, 2013-01-12 20:44
2, 2013-01-13 11:12

userid, lastupdate
1, 2013-01-12 22:00
2, 2013-01-13 12:00
3, 2013-01-11 12:00

Με τα παραπάνω, ο userid=1 έχει notifications από το groupid=2, ο userid=2 δεν έχει κάποιο notification, ενώ ο userid=3 έχει notifications από τα groupid=1,2

Απάντηση

Επιστροφή στο “MySQL”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες