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

Simple Optimization SQL Query


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

Δημοσ.

Select *

From A, B

Where a.id = b.a_id

 

O A έχει 1.500.000 εγγραφές

Και ο Β. 15.000.000 εγγραφές περίπου.

 

Το Query κάνει 2 λεπτά περίπου να εκτελεστεί.  Υπάρχει τρόπος βελτίωσης;

 

Ευχαριστώ.

Δημοσ.

Έχουν indices οι στήλες a.id & b.a_id?

 

Επίσης μαζί με το SELECT σου τρέξε και αυτό "SET STATISTICS XML ON" για να δεις το execution plan του query.

Δημοσ.

@katina

Τip: όταν κάνεις ερωτήσεις για βάσεις δεδομένων να γραφείς πάντα και ποια βάση δεδομένων χρησιμοποιείς/ενδιαφέρεσαι.

 

Στο θέμα τώρα, όπως σου είχαμε πει και στο προηγούμενο θέμα που άνοιξες, αν δεν έχεις indexes τότε πρέπει να βάλεις

Δημοσ.

Επίσης, αντί για select *, δοκίμασε να περιορίσεις τα columns σε αυτά που σε ενδιαφέρουν μόνο, γιατί αν τα indexes δεν έχουν στα included columns τα data που σε ενδιαφέρουν, αναγκάζεις το σύστημα να ξαναψάξει για τις εγγραφές για να τραβήξει ό,τι του λείπει.

 

Αφού έχεις και τα indexes δηλωμένα, κάντα ένα copy/paste εδώ, θα βοηθήσει (θεωρητικά).

Δημοσ.

Το Query κάνει 2 λεπτά περίπου να εκτελεστεί.  Υπάρχει τρόπος βελτίωσης;

 

Το query που δίνεις κάνει cross join. Θεωρώ πιθανό ότι δεν ξέρεις τι σημαίνει cross join οπότε δε θα ρωτήσω γιατί, απλά κάνε αυτό:

SELECT * FROM a INNER JOIN b ON a.id = b.a_id

Θεωρητικά υπάρχει διαφορά ανάμεσα σ' αυτό που κάνεις τώρα και αυτό που προτείνω εδώ, αλλά αν το a.id είναι primary key πρακτικά δεν υπάρχει.

Δημοσ.

Το query που δίνεις κάνει cross join. Θεωρώ πιθανό ότι δεν ξέρεις τι σημαίνει cross join οπότε δε θα ρωτήσω γιατί, απλά κάνε αυτό:

SELECT * FROM a INNER JOIN b ON a.id = b.a_id

Θεωρητικά υπάρχει διαφορά ανάμεσα σ' αυτό που κάνεις τώρα και αυτό που προτείνω εδώ, αλλά αν το a.id είναι primary key πρακτικά δεν υπάρχει.

 

Δεν κάνει cross join όμως 

Δημοσ.

Αλλά? Cross είναι, απλά το φιλτράρει για να καταλήξει σε "σχεδόν inner".

 

Με αυτή την σύνταξη εχουν γραφτεί εκατομμύρια γραμμές σε Oracle DB εδω και δεκαετίες. Λες να κάνει αυτό που λες ?

Δημοσ.

Με αυτή την σύνταξη εχουν γραφτεί εκατομμύρια γραμμές σε Oracle DB εδω και δεκαετίες. Λες να κάνει αυτό που λες ?

 

Δεν έχω ιδέα από Oracle αλλά η αλήθεια είναι πως μετά από 10 sec googling νιώθω πιο βέβαιος από πριν.

 

Anyway, αν κάνω λάθος απλά πές ποιό είναι και γιατί και ποιό είναι το σωστό να γουστάρουμε όλοι.

 

Seems I misread. Cool.  :)

 

Πάντως η απορία παραμένει γιατί αυτό δεν είναι query για 2 λεπτά (!!!!) όταν υπάρχουν indexes. Τα νούμερα δεν τα λες και πολύ μεγάλα.

Δημοσ.

Το συγκεκριμένο query προφανώς και δεν επιστρέφει καρτεσιανό γινόμενο.

 

Πραγματικά τα πιο διαστροφικά πράγματα μπορείς να τα ακούσεις από κάποιον που προσπαθεί να ερμηνεύσει γιατί ένα query δεν έχει το αναμενόμενο performance. Να βάλουμε order by, να βάλουμε limit, να αλλάξουμε font... και αφού όλα αυτά αποτύχουν αρχίζει να αναφέρεται για το rdbms λες και έχει ψυχή, νοημοσύνη.

 

Well, τα rdbms αυτού του επιπέδου είναι πιο complex από λειτουργικά συστήματα. Με το input κάθε πικραμένου developer πρέπει να υπολογιστεί το optimal execution plan στον ελάχιστο δυνατό χρόνο. Ας συνυπολογίσουμε σε όλα αυτά τα όποια bugs και ιδιαιτερότητες όλες αυτές οι εκατομμύρια γραμμές κώδικα αυτών των συστημάτων μπορεί να έχουν.

 

Σταματήστε να μαντεύετε the fuck, ο μόνος τρόπος πέρα από κάποια text book cases να καταλάβεις τι στα @@ γίνεται είναι να δεις το execution plan.

 

Indexes υπάρχουν, όπως και λεφτά... Μερικά πολύ βασικά πράγματα, δεδομένου ότι δεν δίνεις exec plan.

  • Οι πίνακες έχουν indexes... αλλά σε άσχετα columns.
  • Ακόμη και εάν τα 2 συγκεκριμένα columns έχουν index, στο select φέρνεις τα πάντα όλα. Εάν τα indexes δεν είναι clustered πρέπει για κάθε row να γίνει key lookup ώστε να γίνουν fetch τα data από το clustered.
  • Εάν είναι clustered, υπάρχει περίπτωση το μέγεθος των δεδομένων να είναι μεγάλο. Το καλύτερο perf θα το πάρεις από non clustered index seek, όσο μικρότερο είναι το μέγεθος του index, τόσο λιγότερα είναι τα iops που χρειάζεσαι να το σκανάρεις.
  • Οι πίνακες μπορεί να έχουν user uploads και να είναι 5mb κάθε row...
  • Το rdbms είναι στην Αμερική και χρησιμοποιείς modem 56k να συνδεθείς.
  • Like 3
Δημοσ.

Select *

From A, B

Where a.id = b.a_id

 

O A έχει 1.500.000 εγγραφές

Και ο Β. 15.000.000 εγγραφές περίπου.

 

Το Query κάνει 2 λεπτά περίπου να εκτελεστεί.  Υπάρχει τρόπος βελτίωσης;

 

Ευχαριστώ.

 

Όπως αναφέρθηκε πολύ σωστά παραπάνω, μόνο από το πλάνο που παράγει ο optimizer (indices, αλγόριθμος εκτέλεσης join, χωράει κάποιο ή και τα 2 tables  στην μνήμη, υπάρχει κάποια ενδιαφέρουσα ταξινόμηση στους πίνακαες κλπ) μπορείς να καταλάβεις τί κάνει το συγκεκριμένο DBMS που χρησιμοποιείς.

 

Το αν ο πίνακας Α ή Β έχει 1.000.000 η 10.000.000 rows μπορεί να είναι παραπλανητικό και παίζει κυρίως ρόλο στο πλήθος των συγκρίσεων που θα γίνει κατά την εκτέλεση του join, οι οποίες από τους σημερινούς επεξεργαστές γίνονται γρήγορα.

 

Αυτό που έχει περισσότερο νόημα σαν γνώση είναι το πλήθος των rows σε συνάρτηση με το μέγεθος κάθε row αφού ο κύριος παράγοντας κόστους σε ένα centralized DBMS είναι το I/O με τον δίσκο. Μπορεί σε ένα table με 10.000.000 rows να υπάρχει 1 μόνο column με boolean και ένα άλλο table με 1.000.000 rows να έχει 100 columns με ints. Αρα το I/O του δεύτερου είναι πιο ακριβό.  

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

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

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

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

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

Σύνδεση

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

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