SQL Server 2008 - Partycjonowanie i indeksy klastrowe

16

Przedmówię więc, mówiąc, że nie mam całkowitej kontroli nad moim projektem db, więc wielu aspektów obecnego systemu nie można zmienić na potrzeby tego scenariusza.

Komentarze na temat tego, w jaki sposób powinniśmy przemyśleć aspekty projektu, są prawdopodobnie poprawne, ale nie są pomocne :)

Mam bardzo duży stół o szerokości około 150 pól i rzędach około 600 m, który napędza dużą liczbę procesów. Jest to sytuacja w hurtowni danych, więc nie mamy ŻADNYCH aktualizacji / wstawek poza zaplanowanym procesem ładowania, więc jest mocno indeksowana.

Podjęto decyzję, aby spróbować podzielić ten stół na partycje i mam pewne obawy dotyczące indeksowania podzielonej na partycje tabeli. Nie mam żadnego doświadczenia z partycjonowaniem, więc każde wejście lub linki są mile widziane. Nie mogłem znaleźć konkretnie tego, czego szukam na BOL lub msdn.

Obecnie skupiamy się na polu, który nazwiemy, IncidentKeyktóry jest varchar(50)i nie jest unikalny - moglibyśmy mieć od 1 do 100 rekordów z tym samym IK(proszę nie komentować). Często otrzymujemy nowe dane na starych IncidentKeyrekordach, więc nie są one również sekwencyjne.

Rozumiem, że muszę dołączyć moje pole partycji IncidentDate, do mojego klastrowego klucza indeksu, aby partycja działała poprawnie. Myślę, że tak będzie IncidentKey, IncidentDate.

Pytanie brzmi: w jaki sposób mechanika indeksu klastrowego będzie działać na kluczu 2-częściowym w tabeli partycjonowanej, jeśli rekord na „nowej” partycji powinien znajdować się przed rekordem na „starej” partycji w indeksie klastrowym?

Na przykład mam 5 rekordów:

IncidentKey    Date

ABC123        1/1/2010
ABC123        7/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010
XYZ999        7/1/2010

Jeśli otrzymam nowy rekord ABC123, 2/1/2011, będzie on musiał znajdować się w indeksie klastrowym PRZED XYZ999, 1/1/2010 . Jak to działa?

Zakładam fragmentację i wskaźniki, ale nie mogę znaleźć żadnych informacji na temat fizycznej pamięci masowej i konfiguracji indeksów klastrowanych niepartycjonowanych w tabelach partycjonowanych z kluczami dwuczęściowymi.

JNK
źródło
Dlaczego podjęto decyzję o podziale tabeli? Jakie są oczekiwane korzyści z partycjonowania?
Remus Rusanu
@Remus - Właściwie to robię to jako test, więc będziemy mieć jedną partycjonowaną i jedną niepartycjonowaną wersję. Oczekiwaną korzyścią są zmniejszone czasy ładowania i czasy kompilacji indeksu. Wykonujemy comiesięczne operacje ETL, które trwają około tygodnia i mamy nadzieję, że to znacznie skróci ten czas. Mamy również wdrożenie około 3 TB, które mamy nadzieję zmniejszyć dzięki temu.
JNK

Odpowiedzi:

18

Stół podzielony na partycje przypomina bardziej zestaw pojedynczych zestawionych ze sobą stołów. Więc na przykładzie klastrowania według IncidentKeyi dzielenia według IncidentDatepowiedz, że funkcja partycjonowania dzieli tabele na dwie partycje, tak że 1/1/2010 znajduje się na partycji 1, a 7/1/2010 to partycja druga. Dane zostaną rozmieszczone na dysku jako:

Partition 1:
IncidentKey    Date
ABC123        1/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010

Partition 2:
IncidentKey    Date
ABC123        7/1/2010
XYZ999        7/1/2010

Na niskim poziomie są naprawdę dwa odrębne zestawy wierszy. Jest to procesor zapytań, który daje złudzenie pojedynczej tabeli, tworząc plany, które razem wyszukują, skanują i aktualizują wszystkie zestawy wierszy.

Powiedzmy, że każdy wiersz w dowolnym indeksie nieklastrowanym będzie miał klastrowany klucz indeksu, któremu odpowiada ABC123,7/1/2010. Ponieważ klastrowany klucz indeksu zawsze zawiera kolumnę klucza partycjonowania, silnik zawsze będzie wiedział, w jakiej partycji (zestawie wierszy) indeksu klastrowanego szukać tej wartości (w tym przypadku w partycji 2).

Teraz, gdy masz do czynienia z partycjonowaniem, musisz rozważyć, czy twoje indeksy NC będą wyrównane (indeks NC jest podzielony dokładnie tak samo jak indeks klastrowany) czy niezarównane (indeks NC nie jest podzielony na partycje lub podzielony inaczej niż indeks klastrowany) . Niepasujące indeksy są bardziej elastyczne, ale mają pewne wady:

  • indeksy nieprzystosowane wymagają dużej ilości pamięci dla niektórych planów zapytań
  • nieprzystosowane indeksy uniemożliwiają wydajne operacje przełączania partycji

Użycie wyrównanych indeksów rozwiązuje te problemy, ale przynosi własny zestaw problemów, ponieważ ta fizyczna opcja projektowania pamięci masowej przenika do modelu danych:

  • wyrównane indeksy oznaczają, że unikalne ograniczenia nie mogą być już tworzone / egzekwowane (z wyjątkiem kolumny partycjonowania)
  • wszystkie klucze obce odnoszące się do tabeli podzielonej na partycje muszą zawierać klucz podziału w relacji (ponieważ klucz podziału jest ze względu na wyrównanie w każdym indeksie), a to z kolei wymaga, aby wszystkie tabele odwołujące się do podzielonej tabeli zawierały wartość kolumny klucza podziału. Pomyśl Order-> OrderDetails, jeśli Zamówienia mają OrderID, ale są podzielone na partycje według OrderDate, to OrderDetails musi zawierać nie tylko OrderID, ale także OrderDate, aby poprawnie zadeklarować ograniczenie klucza obcego.

Efekty, o których rzadko mówiłem na początku projektu, który wdraża partycjonowanie, ale istnieją i mają poważne konsekwencje.

Jeśli uważasz, że wyrównane indeksy są rzadkim lub skrajnym przypadkiem, zastanów się: w wielu przypadkach podstawą rozwiązań ETL i rozwiązań partycjonujących jest szybkie przełączanie tabel pomostowych. Przełączanie operacji wymaga wyrównanych indeksów.

Aha, jeszcze jedno: cały mój argument na temat kluczy obcych i efekt falowania dodania wartości kolumny partycjonującej do innych tabel dotyczy w równym stopniu sprzężeń .

Remus Rusanu
źródło
Idealnie, właśnie tego szukałem. Będziemy musieli użyć wyrównanych indeksów b / c zamiana jest częścią losowania dla tego, co chcemy z tym zrobić. Robimy również TON grupujących funkcje agregujące na tym IncidentKeypolu, co myślę, że poważnie to utrudni. Doceniam wszystkie szczegóły!
JNK
Zwykle zalety operacji przełączania partycji przeważają nad wszystkimi problemami.
Remus Rusanu
To nasza nadzieja, do zobaczenia wkrótce!
JNK
9

Gdy indeks klastrowy ma wiele partycji, każda partycja ma strukturę drzewa B, która zawiera dane dla tej konkretnej partycji. Na przykład, jeśli indeks klastrowy ma cztery partycje, istnieją cztery struktury B-drzewa; jeden na każdej partycji. Nr ref. Struktury indeksów klastrowych

Specjalne wytyczne dla indeksów podzielonych na partycje

Możesz odbudować określone partycje indeksu partycjonowanego.

na przykład

ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO
Mitch Pszenica
źródło
+1 W przypadku linku przeczytałem specjalne wytyczne, ale przeoczyłem ten akapit. Dalsze pytanie - wykonujemy wiele agregacji w IncidentKeyterenie, czy uważasz, że wpłynęłoby to negatywnie na wydajność (zdaję sobie sprawę, że nadal będę musiał przeprowadzić testy)?
JNK
Nie znam wszystkich twoich konkretnych okoliczności, ale uderza mnie myśl, że lepiej byłoby mieć partycjonowanie według IncidentDate?
Mitch Wheat
Dzielimy partycję w dniu, ale klucz klastrowany jest włączony IncidentKey- wykonujemy mnóstwo połączeń w tym i jest to rodzaj instytucjonalnej rzeczy, której używamy do klastrowania. Testuję alternatywny klucz, ale na razie tego muszę użyć.
JNK