5.1.4

5.1.4 Καθορισμός Μεθόδων Προσπέλασης
**Στόχοι / Προσδοκώμενα Αποτελέσματα** Ο μαθητής/τρια πρέπει να είναι ικανός/ή:
 * να κατανοεί την αλλαγή που προκαλεί η ύπαρξη ευρετηρίου στη μέθοδο προσπέλασης των περιεχόμενα της ΒΔ
 * να εντοπίζει τις στήλες ενός πίνακα για τις οποίες πρέπει να δημιουργηθεί ευρετήριο
 * να χρησιμοποιεί εντολές SQL για να διαχειρίζεται ευρετήρια (δημιουργία, διαγραφή)
 * να κατανοεί πως επηρεάζεται ο χρόνος εκτέλεσης διαφορετικών τύπων ερωτημάτων (ανάκτηση, εισαγωγή, ενημέρωση, διαγραφή) από την ύπαρξη ευρετηρίου

Ο τρόπος που γίνεται η προσπέλαση των περιεχομένων μιας ΒΔ όταν υποβάλλονται ερωτήματα έχει μεγάλη σημασία, καθώς επηρεάζει το **χρόνο απόκρισης της ΒΔ, δηλαδή το χρόνο που απαιτείται για να εμφανιστούν τα αποτελέσματα ενός ερωτήματος**. Καθώς τα περισσότερα ερωτήματα αφορούν συνήθως ανάκτηση δεδομένων, είναι σημαντικό ο χρόνος εκτέλεσης των εντολών SELECT να μην είναι μεγάλος. Υπάρχουν περιπτώσεις που για να εκτελεστεί μια εντολή SELECT το ΣΔΒΔ πρέπει να διαβάσει κάθε γραμμή ενός πίνακα προκειμένου να επιλέξει τις γραμμές που θα επιστραφούν ως αποτέλεσμα του ερωτήματος. Αυτό συμβαίνει όταν η εντολή SELECT:
 * περιέχει συνθήκη (WHERE),
 * περιέχει συναρτήσεις για εύρεση μέγιστης (MAX) και ελάχιστης (MIN) τιμής,
 * απαιτεί ταξινόμηση των αποτελεσμάτων (ORDER BY),
 * απαιτεί ομαδοποίηση των αποτελεσμάτων (GROUP BY).

Για παράδειγμα, στη ΒΔ //mathitologio// υπάρχει ο πίνακας //Μάθημα(Όνομα, Ώρες)// με τις εβδομαδιαίες ώρες διδασκαλίας κάθε μαθήματος. Για να εμφανίσουμε τα μαθήματα που διδάσκονται 4 ώρες την εβδομάδα, θα υποβάλουμε το ακόλουθο ερώτημα: code format="sql" SELECT * FROM Μάθημα WHERE Ώρες=4; code Για το συγκεκριμένο ερώτημα, το ΣΔΒΔ θα διαβάσει κάθε γραμμή του πίνακα //Μάθημα// και για κάθε γραμμή θα ελέγξει αν η τιμή της στήλης //Ώρες// είναι 4. Όσες γραμμές ικανοποιούν αυτή τη συνθήκη θα συμπεριληφθούν στα αποτελέσματα τους ερωτήματος.

Συνεχίζοντας το προηγούμενο παράδειγμα, αν θέλουμε να βρούμε το μέγιστο αριθμό ωρών που διδάσκεται ένα μάθημα θα υποβάλουμε το ακόλουθο ερώτημα: code format="sql" SELECT MAX(Ώρες) FROM Μάθημα; code Για το συγκεκριμένο ερώτημα, το ΣΔΒΔ θα διαβάσει από κάθε γραμμή του πίνακα //Μάθημα// την τιμή της στήλης //Ώρες// ώστε να βρει τη μέγιστη τιμή της στήλης.

Γίνεται λοιπόν κατανοητό ότι όσο περισσότερες γραμμές περιέχει ένας πίνακας τόσο αυξάνεται ο χρόνος εκτέλεσης μιας εντολής SELECT. Αν ο χρόνος αυτός δεν είναι αποδεκτός από τους χρήστες της ΒΔ τότε η ΒΔ δεν θα χρησιμοποιηθεί. Φανταστείτε για παράδειγμα τι θα συμβεί αν η ΒΔ που εξυπηρετεί τα ΑΤΜ μιας τράπεζας χρειάζεται μερικά λεπτά (αντί για δευτερόλεπτα) για να επιστρέψει αποτελέσματα σχετικά με το υπόλοιπο ενός λογαριασμού.

Ο χρόνος εκτέλεσης μιας εντολής SELECT μπορεί να μειωθεί αν χρησιμοποιηθεί **ευρετήριο (index)**. Η έννοια του ευρετηρίου είναι γνωστή καθώς χρησιμοποιείται και σε τομείς εκτός της Πληροφορικής. Για παράδειγμα, αρκετά βιβλία στο τέλος έχουν ευρετήριο όρων που αποτελείται από ζεύγη λέξεων-αριθμών σελίδας. Έτσι αν κάποιος ψάχνει τις σελίδας που αναφέρονται σε κάποιο θέμα δεν χρειάζεται να διαβάσει ολόκληρο το βιβλίο από την πρώτη μέχρι την τελευταία σελίδα, αλλά μπορεί να συμβουλευτεί το ευρετήριο και να μεταφερθεί στην αντίστοιχη σελίδα. Με ανάλογο τρόπο **στις ΒΔ μπορούν να δημιουργηθούν ευρετήρια για τις τιμές που περιέχει μία ή περισσότερες στήλες ενός πίνακα ώστε να επιταχύνονται ερωτήματα που αφορούν τις συγκεκριμένες στήλες**.

Σε όλα τα ΣΔΒΔ **δημιουργείται αυτόματα ευρετήριο για τη στήλη ή τις στήλες που αποτελούν το κύριο κλειδί κάθε πίνακα**. Επιπλέον ευρετήρια θα πρέπει να δημιουργηθούν για στήλες ή συνδυασμό στηλών στις οποίες πραγματοποιούνται συχνά ερωτήματα.

Η δημιουργία ευρετηρίου γίνεται με την εντολή **CREATE INDEX**. Για παράδειγμα, η εντολή code format="sql" CREATE INDEX Ώρες_idx ON Μάθημα(Ώρες); code θα δημιουργήσει ένα ευρετήριο για τη στήλη //Ώρες// του πίνακα //Μάθημα//. Έτσι εντολές SELECT που αφορούν τη στήλη Ώρες θα εκτελούνται πιο γρήγορα καθώς το ΣΔΒΔ θα χρησιμοποιεί το ευρετήριο αντί να ελέγχει τις τιμές της στήλης //Ώρες// για κάθε γραμμή του πίνακα.

Ένα ευρετήριο μπορεί να αφορά περισσότερες από μία στήλες ενός πίνακα. Για παράδειγμα, στη ΒΔ //mathitologio// υπάρχει ο πίνακας //Μαθητής(ΑΜ, Επώνυμο, Όνομα, Πατρώνυμο, Ημερομηνία_Γέννησης, Φύλο, Πόλη)// με τα στοιχεία των μαθητών. Με την εντολή code format="sql" CREATE INDEX ΕπώνυμοΌνομα_idx ON Μαθητής(Επώνυμο, Όνομα); code θα δημιουργήσουμε ένα ευρετήριο για τις στήλες //Επώνυμο// και //Όνομα//. Το ευρετήριο αυτό θα επιταχύνει εντολές SELECT που αφορούν μόνο τη στήλη //Επώνυμο// ή το συνδυασμό των στηλών //Επώνυμο// και //Όνομα//. Εντολές SELECT όμως που αφορούν μόνο τη στήλη //Όνομα// δεν θα ωφεληθούν από το συγκεκριμένο ευρετήριο. Για να γίνει αυτό κατανοητό, έστω τα ακόλουθα ερωτήματα: code format="sql" SELECT * FROM Μαθητής WHERE Επώνυμο=’Παπαδόπουλος’;

SELECT * FROM Μαθητής WHERE Επώνυμο=’Παπαδόπουλος’ AND Όνομα=’Ιωάννης’;

SELECT * FROM Μαθητής WHERE Όνομα=’Ιωάννης’; code Τα πρώτα δύο ερωτήματα θα αξιοποιήσουν το ευρετήριο για τις στήλες //Επώνυμο// και //Όνομα//, ενώ το τρίτο δεν θα μπορέσει να το χρησιμοποιήσει.

Σε ορισμένα ΣΔΒΔ υπάρχει δυνατότητα στην εντολή CREATE INDEX να οριστούν διάφορες παράμετροι, όπως για παράδειγμα η μέθοδος ταξινόμησης των περιεχομένων του ευρετηρίου (αύξουσα ή φθίνουσα), ο τρόπος οργάνωσης των περιεχομένων του ευρετηρίου (π.χ. B+ δέντρο, πίνακας κατακερματισμού), το μέγεθος και ο τρόπος αποθήκευσης των αρχείων που αποτελούν το ευρετήριο.

Η απόφαση για τη δημιουργία ευρετηρίων λαμβάνεται αρχικά από την ομάδα ανάπτυξης μιας εφαρμογής ΒΔ, με βάση τα ερωτήματα που θα υποβάλλονται στη ΒΔ. Επιπλέον ευρετήρια μπορούν να δημιουργηθούν κατά την παραγωγική λειτουργία μιας ΒΔ. Ειδικότερα, ο Διαχειριστής ΒΔ πρέπει να παρακολουθεί τη λειτουργία της ΒΔ για να εντοπίσει ερωτήματα με μεγάλους χρόνους εκτέλεσης (ο τρόπος που γίνεται αυτό εξηγείται σε επόμενη ενότητα). Σε αυτή την περίπτωση, ο Διαχειριστής ΒΔ ακολουθώντας τις οδηγίες της ομάδας ανάπτυξης θα δημιουργήσει τα κατάλληλα ευρετήρια και στη συνέχεια θα κάνει μετρήσεις για να επιβεβαιώσει ότι ο χρόνος απόκρισης της ΒΔ βελτιώθηκε μετά τη δημιουργία των ευρετηρίων. Είναι προφανές ότι για λόγους ασφάλειας, όταν η ΒΔ βρίσκεται σε παραγωγικό περιβάλλον και περιέχει πραγματικά δεδομένα, η δημιουργία ευρετηρίων πρέπει να γίνεται μόνο από τον Διαχειριστή ΒΔ.

Υπάρχουν περιπτώσεις που η ύπαρξη ενός ευρετηρίου δεν είναι επιθυμητή, π.χ. επειδή διαπιστώθηκε ότι το ευρετήριο δεν βελτίωσε τον χρόνο απόκρισης της ΒΔ ή επειδή δεν υποβάλλονται πλέον ερωτήματα που να αξιοποιούν το συγκεκριμένο ευρετήριο. Η διαγραφή ενός ευρετηρίου γίνεται με την εντολή **DROP INDEX**. Για παράδειγμα, με την εντολή code format="sql" DROP INDEX Ώρες_idx ON Μάθημα; code θα διαγραφεί το ευρετήριο στη στήλη //Ώρες// του πίνακα //Μάθημα// που δημιουργήθηκε σε προηγούμενο παράδειγμα.

Η δημιουργία ευρετηρίων **μειώνει** το χρόνο εκτέλεσης των εντολών ανάκτησης γραμμών (SELECT), αλλά **αυξάνει** το χρόνο εκτέλεσης των εντολών εισαγωγής (INSERT), ενημέρωσης (UPDATE) και διαγραφής (DELETE) γραμμών καθώς εκτός από τον πίνακα πρέπει να ενημερωθούν και τα αντίστοιχα ευρετήρια. Γι’ αυτό ο Διαχειριστής ΒΔ θα πρέπει να παρακολουθεί τους χρόνους εκτέλεσης των ερωτημάτων και να διαχειρίζεται κατάλληλα τα ευρετήρια. **Ερωτήσεις / Δραστηριότητες**
 * 1) Συνδεθείτε στο ΣΔΒΔ MySQL με λογαριασμό χρήστη που διαθέτει το προνόμιο INDEX.
 * Μελετήστε τους πίνακες της ΒΔ mathitologio που δημιουργήσατε στο Κεφάλαιο 4. Συζητήστε πιθανά ερωτήματα SQL που μπορεί να υποβάλλονται για να εντοπίσετε στήλες (ή συνδυασμούς στηλών) για τις οποίες θα μπορούσαν να δημιουργηθούν ευρετήρια.
 * Δημιουργήστε τα ευρετήρια που σχεδιάσατε στο προηγούμενο βήμα.