ΒΑΣΕΙΣ ΔΕΔΟΜΕΝΩΝ Πανεπιστήμιο Πειραιώς Τμήμα Ψηφιακών Συστημάτων Μανουσόπουλος Χρήστος cman@unipi.gr
Το ευρετήριο (index) είναι ένα αντικείμενο δεδομένων μέσα στη βάση δεδομένων που καταγράφει τις γραμμές του πίνακα σε τέτοια σειρά, ώστε να γίνεται γρήγορα αναζήτηση. Κάθε ευρετήριο κάθε πίνακα είναι ένα ξεχωριστό αντικείμενο. Τα πρωτεύοντα και τα δευτερεύοντα κλειδιά είναι αυτόματα καταχωρημένα στα ευρετήρια. Γρήγορη πρόσβαση σε ευρετηριοποιημένες στήλες. Κάθε ευρετήριο μπορεί να ανανεωθεί όταν μια γραμμή ανανεώνεται, γεγονός που έχει ως αποτέλεσμα τα ευρετήρια μας να δείχνουν τις αλλαγές που έχουν λάβει χώρα (ανανεώσεις, προσθήκες, διαγραφές). Η καλύτερη και πιο πρακτική μέθοδος είναι να έχουμε 3 ή 4 ευρετήρια ανά πίνακα. Αν χρειάζονται και περισσότερα, μπορούμε ανά περίπτωση να κάνουμε προσθήκη (add) και διαγραφή (drop) για όσα χρειάζονται. Εάν μια βάση δεδομένων περιλαμβάνει ως επί το πλείστο ανανεώσεις, το καλύτερο είναι να χρησιμοποιούμε όσο λιγότερα ευρετήρια γίνεται.
Πολλές φορές δε φαίνεται διαφορά στην ταχύτητα των SQL επερωτήσεων όταν υπάρχουν ή όχι ευρετήρια. Οι λόγοι είναι οι εξής: Απαιτείται πολύ μεγάλος αριθμός εγγραφών προκειμένου να γίνει αντιληπτή θ διαφορά. SQL Server διατηρεί αυτόματα στατιστικά δεδομένα για κάθε στήλη χωριστά, τα οποία έχουν την μορφή ιστογραμμάτων και τα οποία χρησιμοποιούνται ως ευρετήρια όταν δεν έχουν δημιουργηθεί ευρετήρια στις αντίστοιχες στήλες. Τα ευρετήρια βοηθούν τον SQL Server να αναζητήσει τα δεδομένα πιο γρήγορα. Για να καταλάβουμε γιατί είναι χρήσιμα τα ευρετήρια πρέπει να ξέρουμε τα εξής: Ο SQL Server αποθηκεύει τα δεδομένα σε σελίδες(pages) Το μέγεθος της σελίδας είναι προκαθορισμένο -> 8KB (αν έχουμε έναν πίνακα που έχει 1000B μέγεθος γραμμής, μπορούμε να αποθηκεύουμε 8 γραμμές ανά σελίδα.
Όσο πιο πολλές πλήρεις σελίδες δεδομένων έχουμε: Τόσο μεγαλύτερη ΒΔ έχουμε Τόσο περισσότερο χρόνο χρειάζεται για να φτάσουμε σε μια συγκεκριμένη γραμμή. Αν ο πίνακας μας δεν έχει ευρετήρια, αυτό σημαίνει ότι οι γραμμές στις σελίδες δεδομένων αποθηκεύονται χωρίς καμία συγκεκριμένη σειρά. Το πιθανότερο είναι ότι αποθηκεύονται με τη σειρά με την οποία εισήχθησαν. Οπότε τα ευρετήρια χρησιμοποιούνται για να οργανώνουμε τις σελίδες δεδομένων μας.
Clustered ευρετήριο Η λογική σειρά στο ευρετήριο ακολουθεί τη φυσική σειρά των γραμμών στον πίνακα Έχουμε ένα clustered ευρετήριο ανά πίνακα Συνήθως είναι πιο γρήγορο από το non-clustered ευρετήριο. Αν πχ το customer_id χρησιμοποιείται για ένα clustered ευρετήριο, τα δεδομένα θα αναταξινομηθούν βάση αυτού του κλειδιού. Non-clustered ευρετήριο: Αυτά τα ευρετήρια χρησιμοποιούν δείκτες για να μας φέρνουν τα δεδομένα. Μπορούμε να έχουμε παραπάνω από ένα non-clustered ευρετήριο ανά πίνακα. Είναι πιο αργό από το clustered ευρετήριο.
AUTOMATIC STATISTICS Οι SQL Server ΒΔ αυτόματα δημιουργούν και ανανεώνουν στατιστικά. Ο SQL Server χρειάζεται αυτά τα στατιστικά για να κάνει αποτελεσματικά το query processing. Η πληροφορία που αποθηκεύεται περιλαμβάνει: Τον αριθμό των γραμμών και των σελίδων που απασχολούνται από τα δεδομένα του πίνακα Τη χρονική στιγμή κατά την οποία ανανεώθηκαν για τελευταία φορά τα στατιστικά Το μέσο μήκος των κλειδιών μιας στήλης Ιστογράμματα που δείχνουν την κατανομή των δεδομένων σε μια στήλη Μπορούμε να δούμε αυτά τα στατιστικά σε κάθε πίνακα του SQL Server, είτε μέσω της T-SQL είτε μέσω του SQL Server Management Studio. T-SQL επιλογή: sp_helpstats indextesting, 'ALL', η οποία δίνει μια λίστα με όλα τα στατιστικά που έχουν αποθηκευτεί αναφορικά με έναν συγκεκριμένο πίνακα.
Τα ευρετήρια είναι ειδικοί πίνακες αναζήτησης που η μηχανή αναζήτησης της ΒΔ μπορεί να χρησιμοποιήσει για την ταχύτερη ανάκτηση δεδομένων. Πιο απλά, ένα ευρετήριο είναι ένας δείκτης σε δεδομένα σε έναν πίνακα. Βοηθάει την ταχύτερη εκτέλεση SELECT ερωτημάτων και WHERE προτάσεων, αλλά επιβραδύνει την αλλαγή των δεδομένων, με UPDATE και INSERT εντολές. Σύνταξη CREATE [UNIQUE] INDEX όνομα_ευρετηρίου ON όνομα_πίνακα (στηλη1, στήλη2,... στήλη_n); UNIQUE Ο προσδιοριστής UNIQUE δείχνει ότι ο συνδυασμός των τιμών στις ευρετηριοποιημένες στήλες πρέπει να ναι μοναδικός. όνομα_ευρετηρίου Το όνομα που αναθέτουμε στο ευρετήριο. όνομα_πίνακα Το όνομα του πίνακα που δημιουργούμε το ευρετήριο. στηλη1, στήλη2,... στήλη_n Οι στήλες που χρησιμοποιούνται στο ευρετήριο.
Π.χ. CREATE INDEX websites_idx ON websites (site_name); CREATE INDEX websites_idx ON websites (site_name, server); CREATE UNIQUE INDEX websites_idx ON websites (site_name); Στο παραπάνω παράδειγμα το πεδίο site_name πρέπει πάντα να έχει μοναδική τιμή χωρίς διπλότυπα. Είναι μια πολύ καλή τεχνική για την ακεραιότητα των δεδομένων στη ΒΔ εάν επιθυμούμε μοναδικές τιμές σε στήλες που ΔΕΝ περιέχονται στο πρωτεύον κλειδί.
Μετονομασία ευρετηρίου Σύνταξη sp_rename 'table_name.old_index_name', 'new_index_name', 'INDEX'; Διαγραφή ενός ευρετηρίου Σύνταξη DROP INDEX table_name.index_name; Πότε πρέπει να αποφεύγονται: Σε μικρούς πίνακες. Σε πίνακες που έχουν συχνές, μεγάλες μαζικές διεργασίες update ή insert. Σε στήλες που περιέχουν μεγάλο αριθμό NULL τιμών. Σε στήλες που τα δεδομένα τροποποιούνται συχνά.
Παράδειγμα χρήσης ευρετηρίων Δημιουργία test_index_db στον sql server Δημιουργία πίνακα indextesting create table indextesting (column1 int, column2 int); Εισαγωγή δεδομένων στον πίνακα με τη βοήθεια της παρακάτω ρουτίνας use index_testing_db; DECLARE @i int SELECT @i = 1 while (@i<1500000) begin SELECT @i = @i+1; insert into indextesting values (@i, 10000000 - @i); End Εκτέλεση SQL query (χωρίς INDEX, χωρίς STATISTICS, χωρίς Cache) use index_testing_db; select column1, column2 from indextesting where column1 = 5000000; Χρόνος εκτέλεσης:?
Παράδειγμα χρήσης ευρετηρίων Εκτέλεση SQL query (χωρίς INDEX, με STATISTICS, με Cache) use index_testing_db; select column1, column2 from indextesting where column1 = 5000000; Χρόνος εκτέλεσης:? Καθαρισμός της CACHE DBCC DROPCLEANBUFFERS DBCC FREEPROCCACHE Εκτέλεση SQL query (χωρίς INDEX, χωρίς STATISTICS, με Cache) use index_testing_db; drop statistics indextesting._wa_sys_00000001_0ea330e9 select column1, column2 from indextesting where column1 = 5000000; Χρόνος εκτέλεσης:?
Παράδειγμα χρήσης ευρετηρίων Δημιουργία ευρετηρίου στη στήλη column1 use index_testing_db; create index indextesting_column1 on indextesting (column1); Καθαρισμός της CACHE και STATISTICS DBCC DROPCLEANBUFFERS DBCC FREEPROCCACHE drop statistics indextesting._wa_sys_00000001_0ea330e9 Εκτέλεση SQL query (με INDEX, χωρίς STATISTICS, χωρίς Cache) use index_testing_db; select column1, column2 from indextesting where column1 = 5000000; Χρόνος εκτέλεσης:? Παρατηρούμε ότι στα Statistics υπάρχει το indextesting_column1 που αναφέρεται στο ευρετήριο που φτιάξαμε.