Udostępnij za pośrednictwem


Indeksy w dedykowanych tabelach pul SQL w usłudze Azure Synapse Analytics

Zalecenia i przykłady dotyczące indeksowania tabel w dedykowanej puli SQL w usłudze Azure Synapse Analytics.

Typy indeksów

Dedykowana pula SQL oferuje kilka opcji indeksowania, w tym klastrowane indeksy kolumnowe, indeksy klastrowane i nieklastrowane, oraz opcję bez indeksów, znaną również jako sterta.

Aby utworzyć tabelę z indeksem, zobacz dokumentację CREATE TABLE (dedykowana pula SQL).

Klastrowane indeksy kolumnowe

Domyślnie dedykowana pula SQL tworzy indeks klastrowanego magazynu kolumn, gdy nie określono żadnych opcji indeksu w tabeli. Tabele klastrowanego magazynu kolumn oferują zarówno najwyższy poziom kompresji danych, jak i najlepszą ogólną wydajność zapytań. Tabele klastrowanego magazynu kolumn zwykle przewyższają indeks klastrowany lub tabele stert i są zwykle najlepszym wyborem dla dużych tabel. Z tych powodów magazyn kolumn klastrowanych jest najlepszym miejscem do rozpoczęcia, gdy nie masz pewności, jak indeksować tabelę.

Aby utworzyć tabelę klastrowanego magazynu kolumn, określ CLUSTERED COLUMNSTORE INDEX w klauzuli WITH lub pozostaw klauzulę WITH wyłączoną:

CREATE TABLE myTable
  (  
    id int NOT NULL,  
    lastName varchar(20),  
    zipCode varchar(6)  
  )  
WITH ( CLUSTERED COLUMNSTORE INDEX );

Istnieje kilka scenariuszy, w których klastrowany magazyn kolumn może nie być dobrym rozwiązaniem:

  • Tabele w formacie kolumnowym nie obsługują varchar(max), nvarchar(max) i varbinary(max). Rozważ zamiast tego stertę lub indeks klastrowany.
  • Tabele magazynu kolumnowego mogą być mniej wydajne dla danych tymczasowych. Rozważ stertę i tabele tymczasowe.
  • Małe tabele z mniej niż 60 milionami wierszy. Rozważ tabele stert.

Tabele stosu

Kiedy tymczasowo umieszczasz dane w dedykowanej puli SQL, można zauważyć, iż użycie tabeli stert sprawia, że cały proces jest szybszy. Dzieje się tak, ponieważ obciążenia do stert są szybsze niż w przypadku tabel indeksowania, a w niektórych przypadkach kolejne operacje odczytu można wykonać z pamięci podręcznej. Jeśli ładujesz dane tylko w celu przygotowania ich przed uruchomieniem większej liczby przekształceń, ładowanie tabeli do tabeli sterty jest znacznie szybsze niż ładowanie danych do tabeli klastrowanego magazynu kolumn. Ponadto ładowanie danych do tabeli tymczasowej jest szybsze niż ładowanie tabeli do magazynu trwałego. Po załadowaniu danych można utworzyć indeksy w tabeli w celu zwiększenia wydajności zapytań.

Sklasterowane tabele magazynu kolumnowego zaczynają osiągać optymalną kompresję po przekroczeniu liczby 60 milionów wierszy. W przypadku małych tabel odnośników mniej niż 60 milionów wierszy rozważ użycie protokołu HEAP lub indeksu klastrowanego w celu uzyskania szybszej wydajności zapytań.

Aby utworzyć tabelę sterty, określ HEAP w klauzuli WITH.

CREATE TABLE myTable
  (  
    id int NOT NULL,  
    lastName varchar(20),  
    zipCode varchar(6)  
  )  
WITH ( HEAP );

Uwaga

Jeśli często wykonujesz INSERT, UPDATE lub DELETE na tabeli typu sterta, zaleca się uwzględnienie jej ponownego budowania w harmonogramie konserwacji przy użyciu polecenia ALTER TABLE. Na przykład ALTER TABLE [SchemaName].[TableName] REBUILD. Ta praktyka przyczynia się do zmniejszenia fragmentacji, co zwiększa wydajność podczas operacji odczytu.

Indeksy klastrowane i nieklastrowane

Indeksy klastrowane mogą przewyższać klastrowane tabele magazynu kolumn, gdy trzeba szybko pobrać pojedynczy wiersz. W przypadku zapytań, w których wymagane jest wyszukiwanie pojedynczego lub bardzo niewielu wierszy w celu wykonania z ekstremalną szybkością, należy wziąć pod uwagę indeks klastrowany lub indeks pomocniczy, który nie jest klasterowany. Wadą korzystania z indeksu klastrowanego jest to, że jedynie te zapytania odnoszą korzyści, które używają wysoce selektywnego filtru na kolumnie indeksu klastrowanego. Aby poprawić filtrowanie innych kolumn, indeks nieklastrowany można dodać do innych kolumn. Jednak każdy indeks dodawany do tabeli zwiększa zarówno zużycie przestrzeni, jak i czas przetwarzania podczas ładowania.

Aby utworzyć tabelę indeksów klastrowanych, określ indeks KLASTROWANY w klauzuli WITH:

CREATE TABLE myTable
  (  
    id int NOT NULL,  
    lastName varchar(20),  
    zipCode varchar(6)  
  )  
WITH ( CLUSTERED INDEX (id) );

Aby dodać indeks nieklastrowany w tabeli, użyj następującej składni:

CREATE INDEX zipCodeIndex ON myTable (zipCode);

Optymalizacja klastrowanych indeksów kolumnowych magazynu

Tabele kolumn zgrupowanych organizują dane w segmenty. Wysoka jakość segmentów ma kluczowe znaczenie dla osiągnięcia optymalnej wydajności zapytań w tabeli magazynu kolumn. Jakość segmentu określa się na podstawie liczby wierszy w skompresowanej grupie wierszy. Jakość segmentu jest najbardziej optymalna, gdy istnieje co najmniej 100 000 wierszy na skompresowaną grupę wierszy, a wydajność wzrasta, gdy liczba wierszy na grupę wierszy zbliża się do 1 048 576, co jest maksymalną liczbą wierszy, jaką może zawierać grupa wierszy.

Poniższy widok można utworzyć i użyć w systemie do obliczenia średniej liczby wierszy na grupę wierszy oraz do zidentyfikowania nieoptymalnych indeksów kolumnowych klastra. Ostatnia kolumna w tym widoku generuje instrukcję SQL, która może służyć do ponownego kompilowania indeksów.

CREATE VIEW dbo.vColumnstoreDensity
AS
SELECT
        GETDATE()                                                               AS [execution_date]
,       DB_Name()                                                               AS [database_name]
,       s.name                                                                  AS [schema_name]
,       t.name                                                                  AS [table_name]
,       MAX(p.partition_number)                                                 AS [table_partition_count]
,       SUM(rg.[total_rows])                                                    AS [row_count_total]
,       SUM(rg.[total_rows])/COUNT(DISTINCT rg.[distribution_id])               AS [row_count_per_distribution_MAX]
,       CEILING((SUM(rg.[total_rows])*1.0/COUNT(DISTINCT rg.[distribution_id]))/1048576) AS [rowgroup_per_distribution_MAX]
,       SUM(CASE WHEN rg.[State] = 0 THEN 1                   ELSE 0    END)    AS [INVISIBLE_rowgroup_count]
,       SUM(CASE WHEN rg.[State] = 0 THEN rg.[total_rows]     ELSE 0    END)    AS [INVISIBLE_rowgroup_rows]
,       MIN(CASE WHEN rg.[State] = 0 THEN rg.[total_rows]     ELSE NULL END)    AS [INVISIBLE_rowgroup_rows_MIN]
,       MAX(CASE WHEN rg.[State] = 0 THEN rg.[total_rows]     ELSE NULL END)    AS [INVISIBLE_rowgroup_rows_MAX]
,       AVG(CASE WHEN rg.[State] = 0 THEN rg.[total_rows]     ELSE NULL END)    AS [INVISIBLE_rowgroup_rows_AVG]
,       SUM(CASE WHEN rg.[State] = 1 THEN 1                   ELSE 0    END)    AS [OPEN_rowgroup_count]
,       SUM(CASE WHEN rg.[State] = 1 THEN rg.[total_rows]     ELSE 0    END)    AS [OPEN_rowgroup_rows]
,       MIN(CASE WHEN rg.[State] = 1 THEN rg.[total_rows]     ELSE NULL END)    AS [OPEN_rowgroup_rows_MIN]
,       MAX(CASE WHEN rg.[State] = 1 THEN rg.[total_rows]     ELSE NULL END)    AS [OPEN_rowgroup_rows_MAX]
,       AVG(CASE WHEN rg.[State] = 1 THEN rg.[total_rows]     ELSE NULL END)    AS [OPEN_rowgroup_rows_AVG]
,       SUM(CASE WHEN rg.[State] = 2 THEN 1                   ELSE 0    END)    AS [CLOSED_rowgroup_count]
,       SUM(CASE WHEN rg.[State] = 2 THEN rg.[total_rows]     ELSE 0    END)    AS [CLOSED_rowgroup_rows]
,       MIN(CASE WHEN rg.[State] = 2 THEN rg.[total_rows]     ELSE NULL END)    AS [CLOSED_rowgroup_rows_MIN]
,       MAX(CASE WHEN rg.[State] = 2 THEN rg.[total_rows]     ELSE NULL END)    AS [CLOSED_rowgroup_rows_MAX]
,       AVG(CASE WHEN rg.[State] = 2 THEN rg.[total_rows]     ELSE NULL END)    AS [CLOSED_rowgroup_rows_AVG]
,       SUM(CASE WHEN rg.[State] = 3 THEN 1                   ELSE 0    END)    AS [COMPRESSED_rowgroup_count]
,       SUM(CASE WHEN rg.[State] = 3 THEN rg.[total_rows]     ELSE 0    END)    AS [COMPRESSED_rowgroup_rows]
,       SUM(CASE WHEN rg.[State] = 3 THEN rg.[deleted_rows]   ELSE 0    END)    AS [COMPRESSED_rowgroup_rows_DELETED]
,       MIN(CASE WHEN rg.[State] = 3 THEN rg.[total_rows]     ELSE NULL END)    AS [COMPRESSED_rowgroup_rows_MIN]
,       MAX(CASE WHEN rg.[State] = 3 THEN rg.[total_rows]     ELSE NULL END)    AS [COMPRESSED_rowgroup_rows_MAX]
,       AVG(CASE WHEN rg.[State] = 3 THEN rg.[total_rows]     ELSE NULL END)    AS [COMPRESSED_rowgroup_rows_AVG]
,       'ALTER INDEX ALL ON ' + s.name + '.' + t.NAME + ' REBUILD;'             AS [Rebuild_Index_SQL]
FROM    sys.[dm_pdw_nodes_db_column_store_row_group_physical_stats] rg
JOIN    sys.[pdw_nodes_tables] nt                   ON  rg.[object_id]          = nt.[object_id]
                                                    AND rg.[pdw_node_id]        = nt.[pdw_node_id]
                                                    AND rg.[distribution_id]    = nt.[distribution_id]
JOIN    sys.[pdw_permanent_table_mappings] mp                 ON  nt.[name]               = mp.[physical_name]
JOIN    sys.[tables] t                              ON  mp.[object_id]  = t.[object_id]
JOIN    sys.[schemas] s                             ON t.[schema_id]    = s.[schema_id]
JOIN    sys.[partitions] p                          ON P.object_id      = t.object_id
GROUP BY
        s.[name]
,       t.[name];

Po utworzeniu widoku uruchom to zapytanie, aby zidentyfikować tabele z grupami wierszy z mniej niż 100-K wierszy. Jeśli szukasz bardziej optymalnej jakości segmentu, możesz zwiększyć próg 100 K.

SELECT    *
FROM    [dbo].[vColumnstoreDensity]
WHERE    COMPRESSED_rowgroup_rows_AVG < 100000
        OR INVISIBLE_rowgroup_rows_AVG < 100000;

Po uruchomieniu zapytania możesz zacząć przeglądać dane i analizować wyniki. W tej tabeli wyjaśniono, czego należy szukać w analizie grup wierszy.

Kolumna Jak używać tych danych
[liczba_partycji_w_tabeli] Jeśli tabela jest podzielona na partycje, możesz spodziewać się wyższej liczby otwartych grup wierszy. Każda partycja w dystrybucji może teoretycznie mieć skojarzoną z nią otwartą grupę wierszy. Uwzględnij to w analizie. Mała tabela, która została podzielona na partycje, może zostać zoptymalizowana przez całkowite usunięcie partycjonowania, ponieważ poprawiłoby to kompresję.
[row_count_total] Łączna liczba wierszy dla tabeli. Na przykład możesz użyć tej wartości do obliczenia wartości procentowej wierszy w stanie skompresowanym.
[row_count_per_distribution_MAX] Jeśli wszystkie wiersze są równomiernie rozłożone, ta wartość będzie docelową liczbą wierszy dla każdej dystrybucji. Porównaj tę wartość z compressed_rowgroup_count.
[COMPRESSED_rowgroup_rows] Całkowita liczba wierszy w formacie kolumnowym dla tabeli.
[COMPRESSED_rowgroup_rows_AVG] Jeśli średnia liczba wierszy jest znacznie mniejsza niż maksymalna liczba wierszy dla grupy wierszy, rozważ użycie funkcji CTAS lub ALTER INDEX REBUILD w celu ponownego skompresowania danych
[COMPRESSED_rowgroup_count] Liczba grup wierszy w formacie magazynu kolumn. Jeśli ta liczba jest bardzo wysoka względem tabeli, oznacza to, że gęstość składowania kolumnowego jest niska.
[COMPRESSED_rowgroup_rows_DELETED] Wiersze są logicznie usuwane w formacie kolumnowym. Jeśli liczba jest duża względem rozmiaru tabeli, rozważ ponowne utworzenie partycji lub ponowne skompilowanie indeksu, ponieważ spowoduje to usunięcie ich fizycznie.
[COMPRESSED_rowgroup_rows_MIN] Użyj tej funkcji z kolumnami AVG i MAX, aby zrozumieć zakres wartości dla grup wierszy w magazynie kolumn. Niska wartość powyżej progu obciążenia (102 400 na każdą partycję w wyrównanym rozkładzie) sugeruje, że optymalizacje są dostępne w procesie ładowania danych.
[COMPRESSED_rowgroup_rows_MAX] Jak powyżej
[OPEN_rowgroup_count] Otwarte grupy wierszy są normalne. Można by rozsądnie oczekiwać jednej grupy wierszy OPEN na rozkład tabeli (60). Nadmierne liczby sugerują ładowanie danych między partycjami. Dokładnie sprawdź strategię partycjonowania, aby upewnić się, że jest to dźwięk
[OPEN_rowgroup_rows] Każda grupa wierszy może zawierać maksymalnie 1 048 576 wierszy. Użyj tej wartości, aby zobaczyć, jak pełne są obecnie otwarte grupy wierszy
[OPEN_rowgroup_rows_MIN] Otwarte grupy wskazują, że dane są ładowane do tabeli lub że poprzednie obciążenie rozlało pozostałe wiersze do tej grupy wierszy. Użyj kolumn MIN, MAX, AVG, aby zobaczyć, ile danych jest usiadnych w grupach wierszy OPEN. W przypadku małych tabel może to być 100% wszystkich danych. W tym przypadku ALTER INDEX REBUILD w celu wymuszenia użycia danych w magazynie kolumn.
[OPEN_rowgroup_rows_MAX] Jak powyżej
[OPEN_rowgroup_rows_AVG] Jak powyżej
[CLOSED_rowgroup_rows] Przyjrzyj się zamkniętym wierszom grupy jako formie kontroli.
[CLOSED_rowgroup_count] Liczba zamkniętych grup wierszy powinna być niska, jeśli w ogóle są zauważalne. Zamknięte grupy wierszy można przekonwertować na skompresowane grupy wierszy przy użyciu ALTER INDEX ... ZREORGANIZOWANIE polecenia. Nie jest to jednak zwykle wymagane. Zamknięte grupy są automatycznie konwertowane na grupy wierszy w magazynie kolumnowym przez proces "przenoszenia krotek".
[CLOSED_rowgroup_rows_MIN] Zamknięte grupy wierszy powinny mieć bardzo wysoki współczynnik wypełnienia. Jeśli szybkość wypełnienia zamkniętej grupy wierszy kolumnowych jest niska, wymagana jest dalsza analiza kolumnowego magazynu danych.
[CLOSED_rowgroup_rows_MAX] Jak powyżej
[CLOSED_rowgroup_rows_AVG] Jak powyżej
[Rebuild_Index_SQL] SQL do odbudowy indeksu kolumnowego dla tabeli

Wpływ konserwacji indeksu

Kolumna Rebuild_Index_SQL w vColumnstoreDensity widoku zawiera instrukcję ALTER INDEX REBUILD , która może służyć do ponownego kompilowania indeksów. Podczas ponownego kompilowania indeksów upewnij się, że przydzielasz wystarczającą ilość pamięci do sesji, która ponownie kompiluje indeks. W tym celu zwiększ klasę zasobów użytkownika, który ma uprawnienia do ponownego kompilowania indeksu w tej tabeli do zalecanego minimum. Aby zapoznać się z przykładem, zobacz Ponowne kompilowanie indeksów w celu poprawy jakości segmentów w dalszej części tego artykułu.

W przypadku tabeli z uporządkowanym indeksem kolumnowym z klastrowaniem ALTER INDEX REBUILD ponownie posortuje dane, korzystając z tempdb. Monitorowanie bazy danych tempdb podczas operacji ponownego kompilowanie. Jeśli potrzebujesz więcej przestrzeni w tempdb, zwiększ pulę bazodanową. Skaluj z powrotem w dół po zakończeniu ponownego kompilowania indeksu.

W przypadku tabeli z uporządkowanym klastrowanym indeksem kolumnowym, ALTER INDEX REORGANIZE nie sortuje danych ponownie. Aby ponownie sortować dane, użyj polecenia ALTER INDEX REBUILD.

Aby uzyskać więcej informacji na temat uporządkowanych klastrowanych indeksów magazynu kolumn, zobacz Dostrajanie wydajności z uporządkowanym klastrowanym indeksem magazynu kolumn.

Przyczyny niskiej jakości indeksu kolumnowego

Jeśli zidentyfikowałeś tabele o niskiej jakości segmentów, chcesz znaleźć główną przyczynę. Poniżej przedstawiono kilka innych typowych przyczyn niskiej jakości segmentu:

  1. Obciążenie pamięci podczas budowania indeksu
  2. Duża liczba operacji DML
  3. Małe lub stopniowe operacje ładowania
  4. Zbyt wiele partycji

Te czynniki mogą spowodować, że indeks kolumnowy będzie miał znacznie mniej niż optymalne 1 milion wierszy na grupę wierszy. Mogą również powodować przekierowanie wierszy do grupy wierszy różnicowych zamiast do skompresowanej grupy wierszy.

Uwaga

Tabele kolumnowe zwykle nie wypychają danych do skompresowanego segmentu kolumnowego, dopóki nie będzie więcej niż 1 milion wierszy na tabelę. Jeśli tabela z klastrowanym indeksem magazynu kolumn zawiera wiele otwartych grup wierszy z całkowitą liczbą wierszy, które nie spełniają progu kompresji (1 milion wierszy), te grupy wierszy pozostaną otwarte i będą przechowywane jako dane wierszy. W związku z tym zwiększy to rozmiar bazy danych dystrybucji, ponieważ nie zostaną skompresowane. Ponadto te otwarte grupy wierszy nie będą korzystać z CCI i będą wymagały większej ilości zasobów do utrzymania. Może być zalecane użycie ALTER INDEX REORGANIZE.

Presja na pamięć podczas budowania indeksu

Liczba wierszy na skompresowaną grupę wierszy jest bezpośrednio powiązana z szerokością wiersza i ilością pamięci dostępnej do przetworzenia grupy wierszy. Jeśli wiersze są zapisywane w tabelach magazynu kolumn przy dużym wykorzystaniu pamięci, może to spowodować obniżenie jakości segmentów w magazynie kolumn. W związku z tym najlepszym rozwiązaniem jest umożliwienie sesji zapisującej dane do tabel z indeksami columnstore dostępu do możliwie jak największej ilości pamięci. Ponieważ istnieje kompromis między pamięcią a współbieżnością, wskazówki dotyczące odpowiedniej alokacji pamięci zależą od danych w każdym wierszu tabeli, jednostek magazynu danych przydzielonych do systemu oraz liczby miejsc współbieżności, które można przekazać sesji, która zapisuje dane w tabeli.

Duża liczba operacji DML

Duża liczba operacji DML, które aktualizują i usuwają wiersze, może powodować nieefektywność w kolumnowym magazynie danych. Jest to szczególnie istotne, gdy większość wierszy w grupie wierszy jest modyfikowana.

  • Usunięcie wiersza ze skompresowanej grupy wierszy powoduje tylko logicznie oznaczenie wiersza jako usuniętego. Wiersz pozostaje w skompresowanej grupie wierszy do momentu odbudowy partycji lub tabeli.
  • Wstawianie wiersza powoduje dodanie wiersza do wewnętrznej tabeli magazynu wierszy, zwanej grupą wierszy delta. Wstawiony wiersz nie jest konwertowany na magazyn kolumn, dopóki grupa wierszy różnicowych nie zostanie pełna i zostanie oznaczona jako zamknięta. Grupy wierszy są zamykane po osiągnięciu maksymalnej pojemności 1 048 576 wierszy.
  • Aktualizowanie wiersza w formacie magazynu kolumn jest przetwarzane jako usuwanie logiczne, a następnie wstawianie. Wstawiony wiersz może być przechowywany w "delta store".

Operacje aktualizacji wsadowej i wstawiania, które przekraczają próg zbiorczości 102 400 wierszy na partycjonowaną dystrybucję, są przekazywane bezpośrednio do formatu magazynu kolumn. Jednak przy założeniu równomiernej dystrybucji należy zmodyfikować ponad 6,144 miliona wierszy w jednej operacji, aby to się stało. Jeśli liczba wierszy dla danej dystrybucji wyrównanej do partycji jest mniejsza niż 102 400, wiersze przechodzą do delta store i pozostają tam do momentu wstawienia lub zmodyfikowania wystarczającej liczby wierszy, by zakończyć grupę wierszy lub odbudować indeks.

Małe lub trudne operacje ładowania

Małe obciążenia, które przepływają do dedykowanej puli SQL, są również czasami nazywane obciążeniami strumieniowymi. Zazwyczaj reprezentują niemal stały strumień danych pozyskiwanych przez system. Jednak ponieważ ten strumień jest niemal ciągły, liczba wierszy nie jest szczególnie duża. Najczęściej dane są znacznie poniżej progu wymaganego do bezpośredniego ładowania do formatu kolumnowego.

W takich sytuacjach często lepiej jest najpierw wylądować dane w usłudze Azure Blob Storage i pozwolić na gromadzenie ich przed załadowaniem. Ta technika jest często nazywana mikrosadowaniem.

Zbyt wiele partycji

Kolejną rzeczą, którą należy wziąć pod uwagę, jest wpływ partycjonowania na klastrowane tabele magazynu kolumn. Przed partycjonowaniem dedykowana pula SQL dzieli już dane na 60 baz danych. Partycjonowanie dalej dzieli dane. W przypadku partycjonowania danych należy wziąć pod uwagę, że każda partycja potrzebuje co najmniej 1 miliona wierszy, aby skorzystać z klastrowanego indeksu magazynu kolumn. Jeśli podzielisz tabelę na 100 partycji, tabela potrzebuje co najmniej 6 miliardów wierszy, aby skorzystać z klastrowanego indeksu magazynu kolumn (60 dystrybucji 100 partycji 1 milion wierszy ). Jeśli twoja tabela z 100 partycjami nie ma 6 miliardów wierszy, zmniejsz liczbę partycji lub rozważ użycie tabeli typu heap.

Po załadowaniu tabel z danymi wykonaj poniższe kroki, aby zidentyfikować i odbudować tabele przy użyciu klastrowanych indeksów magazynu kolumnowego.

Ponowne kompilowanie indeksów w celu poprawy jakości segmentu

Krok 1. Identyfikowanie lub tworzenie użytkownika używającego odpowiedniej klasy zasobów

Jednym z szybkich sposobów natychmiastowego poprawy jakości segmentu jest odbudowanie indeksu. Powyższy widok zwracany przez program SQL zawiera instrukcję ALTER INDEX REBUILD, która może służyć do ponownego kompilowania indeksów. Podczas ponownego kompilowania indeksów upewnij się, że przydzielasz wystarczającą ilość pamięci do sesji, która ponownie kompiluje indeks. W tym celu zwiększ klasę zasobów użytkownika, który ma uprawnienia do ponownego kompilowania indeksu w tej tabeli do zalecanego minimum.

Poniżej przedstawiono przykład przydzielania większej ilości pamięci użytkownikowi przez zwiększenie ich klasy zasobów. Aby pracować z klasami zasobów, zobacz Klasy zasobów na potrzeby zarządzania obciążeniami.

EXEC sp_addrolemember 'xlargerc', 'LoadUser';

Krok 2. Ponowne kompilowanie klastrowanych indeksów magazynu kolumn przy użyciu użytkownika wyższej klasy zasobów

Zaloguj się jako użytkownik z kroku 1 (LoadUser), który korzysta teraz z wyższej klasy zasobów i wykonaj instrukcje ALTER INDEX. Upewnij się, że ten użytkownik ma uprawnienie ALTER do tabel, w których indeks jest odbudowywany. W tych przykładach pokazano, jak ponownie skompilować cały indeks magazynu kolumn lub jak ponownie skompilować pojedynczą partycję. W przypadku dużych tabel bardziej praktyczne jest ponowne kompilowanie indeksów pojedynczej partycji naraz.

Alternatywnie zamiast ponownego kompilowania indeksu można skopiować tabelę do nowej tabeli przy użyciu funkcji CTAS. W jaki sposób jest najlepszy? W przypadku dużych ilości danych funkcja CTAS jest zwykle szybsza niż ALTER INDEX. W przypadku mniejszych ilości danych funkcja ALTER INDEX jest łatwiejsza w użyciu i nie wymaga wymiany tabeli.

-- Rebuild the entire clustered index
ALTER INDEX ALL ON [dbo].[DimProduct] REBUILD;
-- Rebuild a single partition
ALTER INDEX ALL ON [dbo].[FactInternetSales] REBUILD Partition = 5;
-- Rebuild a single partition with archival compression
ALTER INDEX ALL ON [dbo].[FactInternetSales] REBUILD Partition = 5 WITH (DATA_COMPRESSION = COLUMNSTORE_ARCHIVE);
-- Rebuild a single partition with columnstore compression
ALTER INDEX ALL ON [dbo].[FactInternetSales] REBUILD Partition = 5 WITH (DATA_COMPRESSION = COLUMNSTORE);

Ponowne kompilowanie indeksu w dedykowanej puli SQL jest operacją offline. Aby uzyskać więcej informacji na temat odbudowywania indeksów, zobacz sekcję ALTER INDEX REBUILD w Defragmentacja indeksów magazynu kolumn i ALTER INDEX.

Krok 3. Sprawdź, czy jakość segmentu kolumnowego magazynu danych klastrowanego się poprawiła

Uruchom ponownie zapytanie, które zidentyfikowało tabelę o niskiej jakości segmentu i sprawdź, czy jakość segmentu została ulepszona. Jeśli jakość segmentu nie poprawiła się, może to oznaczać, że wiersze w tabeli są zbyt szerokie. Rozważ użycie wyższej klasy zasobów lub jednostek DWU podczas ponownego kompilowania indeksów.

Ponowne kompilowanie indeksów za pomocą funkcji CTAS i przełączania partycji

W tym przykładzie użyto instrukcji CREATE TABLE AS SELECT (CTAS) i przełączenia partycji w celu ponownego skompilowania partycji tabeli.

-- Step 1: Select the partition of data and write it out to a new table using CTAS
CREATE TABLE [dbo].[FactInternetSales_20000101_20010101]
    WITH    (   DISTRIBUTION = HASH([ProductKey])
            ,   CLUSTERED COLUMNSTORE INDEX
            ,   PARTITION   (   [OrderDateKey] RANGE RIGHT FOR VALUES
                                (20000101,20010101
                                )
                            )
            )
AS
SELECT  *
FROM    [dbo].[FactInternetSales]
WHERE   [OrderDateKey] >= 20000101
AND     [OrderDateKey] <  20010101
;

-- Step 2: Switch IN the rebuilt data with TRUNCATE_TARGET option
ALTER TABLE [dbo].[FactInternetSales_20000101_20010101] SWITCH PARTITION 2 TO  [dbo].[FactInternetSales] PARTITION 2 WITH (TRUNCATE_TARGET = ON);

Aby uzyskać więcej informacji na temat ponownego tworzenia partycji przy użyciu usługi CTAS, zobacz Using partitions in dedicated SQL pool (Używanie partycji w dedykowanej puli SQL).

Aby uzyskać więcej informacji na temat tworzenia tabel, zobacz Tworzenie tabel.