Πολλαπλά joins ή ξεχωριστά queries

Γενικές συζητήσεις για SQL και SQL Servers (RDBMS)

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

Απάντηση
Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από Khronos » 18 Νοέμ 2011 20:34

Έχω αυτό το query που μου φέρνει τις 3 τελευταίες επιχειρήσεις που έχουν καταχωρηθεί μαζί με άλλες πληροφορίες όπως φωτογραφία και σε ποιες κατηγορίες ανήκει η κάθε επιχείρηση.

Το δοκίμασα με 20000 εγγραφές (επιχειρήσεις) που σημαίνει ότι υπάρχουν άλλες 20000 εγγραφές τουλάχιστον για το πολυγλωσσικό κομμάτι και τουλάχιστον 20000 εγγραφές στο συνδετικό πίνακα businesses_categories και έκανε γύρω στα 8 sec για να φέρει τις 3 εγγραφές.

Κώδικας: Επιλογή όλων

SELECT b.id, 
                       bl.title, 
                       b.url_name, 
                       description, 
                       bi.image,
                       
                       GROUP_CONCAT(bc.url_name) as bc_url_name,
                       GROUP_CONCAT(bcl.title) as bc_title,
                       GROUP_CONCAT(bcl.id) as bc_id
                       
                       FROM businesses b 
                       INNER JOIN businesses_lang bl ON b.id = bl.item_id 
                       INNER JOIN businesses_categories b_c ON b.id = b_c.business_id
                       INNER JOIN businesscategories bc ON b_c.category_id = bc.id
                       INNER JOIN businesscategories_lang bcl ON bc.id = bcl.item_id
                       LEFT JOIN businessimages bi ON b.id = bi.business_id AND dfault = 1
                       WHERE bl.locale = 'el' AND bcl.locale = 'el' AND b.published = 1 GROUP BY b.id ORDER BY b.id DESC LIMIT 3
Και ρωτάω, είναι αναμενόμενο να κάνει τόσο χρόνο? Φταίνε τα joins? Μπορεί να γραφτεί καλύτερα το query?
Και τέλος, εσείς πώς θα χειριζόσασταν μια τέτοια περίπτωση? Με πολλαπλά joins και ένα query ή πολλά ξεχωριστά για κάθε πληροφορία που θέλουμε, πχ. 1 query για να φέρουμε τις επιχειρήσεις, 1 - ? queries για να βρούμε τις κατηγορίες και 1 - ? queries για να βρούμε τις φωτογραφίες?

Ελπίζω να μην σας κούρασα! :P

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από Khronos » 19 Νοέμ 2011 13:13

Πρόσθεσα διάφορα indexes και ο χρόνος εκτέλεσης μειώθηκε σημαντικά.
Θα ήθελα να δω πάντως τις απόψεις σας!

Άβαταρ μέλους
CyberCr33p
Honorary Member
Δημοσιεύσεις: 3199
Εγγραφή: 06 Νοέμ 1999 01:00
Τοποθεσία: Αθήνα
Επικοινωνία:

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από CyberCr33p » 19 Νοέμ 2011 14:02

Έχω την εντύπωση ότι τα joins είναι πιο γρήγορα από τα sub-queries. Πάντως θα είχε ενδιαφέρον να βλέπαμε τους χρόνους και με τους 2 τρόπους στο συγκεκριμένο παράδειγμά σου. Στα joins αυτό που θέλει προσοχή είναι να είναι ίδιου τύπου τα πεδία που θα "ενώσεις" ώστε να γίνεται πλήρης χρήση των indexes.

Άβαταρ μέλους
Rapid-eraser
WebDev Moderator
Δημοσιεύσεις: 6851
Εγγραφή: 05 Απρ 2003 17:50
Τοποθεσία: Πειραιάς
Επικοινωνία:

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από Rapid-eraser » 19 Νοέμ 2011 15:17

Βάλε ένα EXPLAIN μπροστά από το query και τρέχτο από command line / phpmysql /gui και δες τι συμβαίνει.
Cu, Rapid-eraser, Tα αγαθά copies κτώνται.
Love is like oxygen, You get too much you get too high
Not enough and you're gonna die, Love gets you high

Άβαταρ μέλους
ThyClub
Honorary Member
Δημοσιεύσεις: 5312
Εγγραφή: 17 Νοέμ 2003 00:21
Τοποθεσία: Hell's Kitchen
Επικοινωνία:

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από ThyClub » 19 Νοέμ 2011 16:09

Κώδικας: Επιλογή όλων

GROUP BY b.id ORDER BY b.id
Εδώ είναι το πρόβλημα σου. Δεν είναι λογικό να σορτάρεις πίνακα 22000 εγγραφών και να τα κάνεις και group. Αν κατάλαβες καλά, σκανάρεις 22000 εγγραφές για να πάρεις μόνο 3

Δοκίμασε έναν άλλο τρόπο με relations ώστε να κάνεις το ίδιο ακριβώς query σε πίνακα κατά πολύ μικρότερο απο αυτόν που έχεις.

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από Khronos » 19 Νοέμ 2011 16:37

Rapid-eraser έγραψε:Βάλε ένα EXPLAIN μπροστά από το query και τρέχτο από command line / phpmysql /gui και δες τι συμβαίνει.
Το δοκίμασα στο phpmyadmin αλλά δεν κατάλαβα και πολλά. Μου βγάζει αυτά. Είναι καλό ή κακό?
Συνημμένα
explain.jpg

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από Khronos » 19 Νοέμ 2011 16:38

ThyClub έγραψε:

Κώδικας: Επιλογή όλων

GROUP BY b.id ORDER BY b.id
Εδώ είναι το πρόβλημα σου. Δεν είναι λογικό να σορτάρεις πίνακα 22000 εγγραφών και να τα κάνεις και group. Αν κατάλαβες καλά, σκανάρεις 22000 εγγραφές για να πάρεις μόνο 3

Δοκίμασε έναν άλλο τρόπο με relations ώστε να κάνεις το ίδιο ακριβώς query σε πίνακα κατά πολύ μικρότερο απο αυτόν που έχεις.
Το group το κάνω επειδή κάθε επιχείρηση ανήκει σε πολλές κατηγορίες και το sort για να πάρω τις τελευταίες 3. Τι εννοείς με relations?

billiaswhs
Δημοσιεύσεις: 346
Εγγραφή: 11 Νοέμ 2004 00:29
Επικοινωνία:

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από billiaswhs » 19 Νοέμ 2011 21:21

Νομίζω και εγώ ότι το group by δημιουργεί το πρόβλημα
γιατί δεν κάνεις μία μετρηση με group by και μία χωρίς.

Ίσως ένα query για να πάρεις τα id
των τριών τελευταίων επιχειρήσεων αφού έτσι και αλλιώς
θέλεις μόνο τρεις και μετά άλλο ένα για να πάρεις τα
δεδομένα τους μπορείς τόσο consuming

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από Khronos » 19 Νοέμ 2011 21:43

Ρε παιδιά, αν το κάνω χωρίς group by θα μου φέρει την ίδια επιχείρηση 3 φορές αν ανήκει πχ σε 3 κατηγορίες.
Το όλο θέμα είναι να γίνει σε ένα query.

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από Khronos » 20 Νοέμ 2011 13:08

@billiaswhs
Ακολούθησα τη συμβουλή σου και το έκανα έτσι.

Κώδικας: Επιλογή όλων

SELECT b.id,
                        b.url_name,
                        bl.title,
                        description, 
                        bi.image,
                        GROUP_CONCAT(b_c.category_id) as bc_id,
                        GROUP_CONCAT(bc.url_name) as bc_url_name,
                        GROUP_CONCAT(bcl.title) as bc_title
                        FROM (SELECT id, url_name FROM businesses WHERE published = 1 ORDER BY id DESC LIMIT 3) b 
                        INNER JOIN businesses_lang bl ON b.id = bl.item_id
                        INNER JOIN businesses_categories b_c ON b.id = b_c.business_id
                        INNER JOIN businesscategories bc ON b_c.category_id = bc.id
                        INNER JOIN businesscategories_lang bcl ON b_c.category_id = bcl.item_id
                        LEFT JOIN businessimages bi ON b.id = bi.business_id AND dfault = 1
                        WHERE bl.locale = 'el' AND bcl.locale = 'el' GROUP BY b.id ORDER BY b.id DESC
Είναι πιο βέλτιστο? Βέβαια από τότε που έβαλα τα indexes οι χρόνοι είναι ίδιοι και για τα 2 queries. Το phpmyadmin μου λέει 0.0009 sec.

billiaswhs
Δημοσιεύσεις: 346
Εγγραφή: 11 Νοέμ 2004 00:29
Επικοινωνία:

Πολλαπλά joins ή ξεχωριστά queries

Δημοσίευση από billiaswhs » 21 Νοέμ 2011 17:05

Γεια χαρά το βέλτιστο είναι αυτό με το χαμηλότερο χρόνο
οπότε αυτό θα φανεί σε μεγάλο data set με indexes,
πάντος μια φορά που έκανα σε ένα πίνaκα
που είχει 1.500.000 εγγραφές join με άλλους είχε σοβαρό πρόβλημα
με τα πολλά join και έκανα περισσότερα και πιο απλά ερωτήματα.

Δοκίμασε τα ερωτήματα τα σε ένα stress test tool

http://www.techrepublic.com/blog/howdoi ... qlslap/133

Απάντηση

Επιστροφή στο “Βάσεις Δεδομένων και SQL - γενικά”

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

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