Partitioned Tables


Technorati Tags:

Στην προηγούμενη έκδοση του SQL Server είχαμε τα partitioned views μέσω των οποίων μπορούσαμε να δούμε πολλαπλούς πίνακες, ενδεχομένως σε διαφορετικούς servers, ως ένα ενιαίο σύνολο. Σε αυτήν την έκδοση μπορούμε να έχουμε σε partionions τον ίδιο τον πίνακα.

Το partitioning γίνεται οριζόντια δηλαδή ένα διαφορετικό set από εγγραφές υπάρχει σε κάθε partition και κάθε ένα από αυτούς κατοικοεδρεύει σε διαφορετικό filegroup.

To πλεονέκτημα είναι ότι είναι ευκολότερη η διαχείριση πινάκων μεγάλου όγκου δεδομένων αφού οι ενέργειες που κάνουμε περιορίζονται μόνο στους πίνακες που αφορούν.

Επίσης, ο query optimizer όταν τρέχει σε συστήματα με 8 επεξεργαστές και άνω, μπορεί να προσαρμόζει το execution plan ώστε να εκτελούνται παράλληλα queries στα partitions.

Πως γίνεται η δουλειά

Αρχικά χρειαζόμαστε ένα PARTITION FUNCTION. Αυτό καθορίζει ποια data πάνε σε ποιό partition.

<br />CREATE PARTITION FUNCTION OrderDatePF (datetime) <br />AS RANGE LEFT FOR VALUES (‘1/1/1997’, ‘1/1/1998’) <br />

Δηλαδή θα σπάσουμε τον πίνακα Orders σε τρεις ομάδες μία ως (προσοχή, όχι «ως και» – RANGE RIGHT) 1/1/1997, μία  από 1/1/1997 ως 1/1/1998 και μία από 1/1/1998 ως σήμερα

Κατόπιν, χρειαζόμαστε ένα PARTITION SCHEME το οποίο θα αντιστοιχήσει τα table partitions σε ανάλογα filegroups

<br />CREATE PARTITION SCHEME OrderDatePS <br />AS PARTITION OrderDatePF TO (filegroup1, filegroup2, filegroup3) <br />

Και τέλος φτιάχνουμε τον πίνακα που θα γίνει partitioned

<br />CREATE TABLE OrdersHistory( <br />                OrderID int PRIMARY KEY, <br />                CustomerID nchar(5), <br />                EmployeeID int , <br />                OrderDate datetime , <br />                RequiredDate datetime , <br />                ShippedDate datetime , <br />                ShipVia int , <br />                Freight money , <br />                ShipName nvarchar(40) , <br />                ShipAddress nvarchar(60) , <br />                ShipCity nvarchar(15) , <br />                ShipRegion nvarchar(15), <br />                ShipPostalCode nvarchar(10) , <br />                ShipCountry nvarchar(15)) <br />ON OrderDatePS(OrderDate) <br />

Αν θα τρέξετε το παραπάνω όμως δεν θα παίξει… Θα πρέπει να το αλλάξετε να γίνει έτσι:

<br />CREATE TABLE OrdersHistory( <br />                OrderID int , <br />                CustomerID nchar(5), <br />                EmployeeID int , <br />                OrderDate datetime , <br />                RequiredDate datetime , <br />                ShippedDate datetime , <br />                ShipVia int , <br />                Freight money , <br />                ShipName nvarchar(40) , <br />                ShipAddress nvarchar(60) , <br />                ShipCity nvarchar(15) , <br />                ShipRegion nvarchar(15), <br />                ShipPostalCode nvarchar(10) , <br />                ShipCountry nvarchar(15), <br />CONSTRAINT PK_OrdersHist PRIMARY KEY CLUSTERED <br />( <br />                OrderID ASC, <br />                OrderDate <br />)) <br />ON OrderDatePS(OrderDate) <br />

Το πιάσατε το κόλπο;

Εδώ η δουλειά έχει τελειώσει. Μένει να τον γεμίσουμε:

<br />INSERT INTO OrdersHistory <br />SELECT * FROM Orders <br />

Και πλέον μπορούμε να τρέξουμε τα query μας.

<br />SELECT OrderID, $partition.OrderDatePF(OrderDate) Partition <br />FROM OrdersHistory <br />

Αυτό το $partition.OrderDatePF(OrderDate) τι είναι; Ένα function που μας επιστρέφει τον αριθμό του partition που βρίσκεται το row…

Το ωραίο της υπόθεσης το άφησα για το τέλος… Η λύση αυτή διαφέρει πολύ σε σχέση με το να κάνει κάποιος το ίδιο σενάριο χειροκίνητα και να συντηρεί τους πίνακες με triggers ή με INSERT INTO SELECT FROM statements. Με το νέο τρόπο, είναι ταχύτατη η μεταφορά δεδομένων από partition σε partition γιατί τα data δεν μεταφέρονται «φυσικά» αλλά απλώς αλλάζουν τα metadata που έχουν να κάνουν με την τοποθεσία αποθήκευσης…