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

Rekomendacje 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 magazynu kolumn, indeksy klastrowane i indeksy nieklastrowane oraz opcję nieindeksowaną znaną również jako sterta.

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

Klastrowane indeksy magazynu kolumn

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, po prostu określ CLUSTERED COLUMNSTORE INDEX ją 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 magazynu kolumn nie obsługują funkcji varchar(max), nvarchar(max) i varbinary(max). Rozważ zamiast tego stertę lub indeks klastrowany.
  • Tabele magazynu kolumn mogą być mniej wydajne w przypadku danych przejściowych. Rozważ stertę, a może nawet tabele tymczasowe.
  • Małe tabele z mniej niż 60 milionami wierszy. Rozważ tabele stert.

Tabele stert

W przypadku tymczasowego lądowania danych w dedykowanej puli SQL może się okazać, że użycie tabeli stert sprawia, że ogólny 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 do etapu 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ń.

Tabele magazynu kolumn klastra zaczynają osiągać optymalną kompresję, gdy istnieje ponad 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ę stert, po prostu określ stos 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 INSERToperacje , UPDATElub DELETE na tabeli stert, zaleca się uwzględnienie ponownego kompilowania tabeli w harmonogramie konserwacji przy użyciu ALTER TABLE polecenia . 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 tylko zapytania, które korzystają z tych, które korzystają z wysoce selektywnego filtru w kolumnie indeksu klastrowanego. Aby poprawić filtrowanie innych kolumn, indeks nieklastrowany można dodać do innych kolumn. Jednak każdy indeks dodawany do tabeli dodaje zarówno przestrzeń, jak i czas przetwarzania do załadowania.

Aby utworzyć tabelę indeksów klastrowanych, po prostu 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 nieklasterowany w tabeli, użyj następującej składni:

CREATE INDEX zipCodeIndex ON myTable (zipCode);

Optymalizowanie klastrowanych indeksów magazynu kolumn

Tabele klastrowanego magazynu kolumn 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, jeśli istnieje co najmniej 100 K wierszy na skompresowaną grupę wierszy i zyskuje wydajność, ponieważ liczba wierszy na grupę wierszy zbliża się do 1048 576 wierszy, co jest największą liczbą wierszy, które może zawierać grupa wierszy.

Poniższy widok można utworzyć i użyć w systemie do obliczenia średnich wierszy na grupę wierszy i zidentyfikować wszystkie nieoptymalne indeksy magazynu kolumn 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]
,    COUNT(DISTINCT rg.[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.[pdw_nodes_column_store_row_groups] 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_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]
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
[table_partition_count] Jeśli tabela jest podzielona na partycje, możesz spodziewać się wyższych liczby otwartych grup wierszy. Każda partycja w dystrybucji może teoretycznie mieć skojarzona 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 na dystrybucję. Porównaj tę wartość z compressed_rowgroup_count.
[COMPRESSED_rowgroup_rows] Całkowita liczba wierszy w formacie magazynu kolumn 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 w stosunku do tabeli, jest to wskaźnik, że gęstość magazynu kolumn jest niska.
[COMPRESSED_rowgroup_rows_DELETED] Wiersze są logicznie usuwane w formacie magazynu kolumn. 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 liczba progowa obciążenia (102 400 na rozkład wyrównany do partycji) sugeruje, że optymalizacje są dostępne w obciążeniu 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 ona dźwiękowa
[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] Spójrz na zamknięte wiersze grupy wierszy jako sprawdzanie kondycji.
[CLOSED_rowgroup_count] Liczba zamkniętych grup wierszy powinna być niska, jeśli w ogóle jest widoczna. 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 magazynu kolumn przez proces "krotki krotki".
[CLOSED_rowgroup_rows_MIN] Zamknięte grupy wierszy powinny mieć bardzo wysoką częstotliwość wypełniania. Jeśli szybkość wypełnienia zamkniętej grupy wierszy jest niska, wymagana jest dalsza analiza magazynu kolumn.
[CLOSED_rowgroup_rows_MAX] Jak powyżej
[CLOSED_rowgroup_rows_AVG] Jak powyżej
[Rebuild_Index_SQL] Sql do ponownego kompilowania indeksu magazynu kolumn 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 ze uporządkowanym klastrowanym indeksem ALTER INDEX REBUILD magazynu kolumn ponownie posortuje dane przy użyciu bazy danych tempdb. Monitorowanie bazy danych tempdb podczas operacji ponownego kompilowanie. Jeśli potrzebujesz więcej miejsca w bazie danych tempdb, przeprowadź skalowanie w górę puli baz danych. Skaluj z powrotem w dół po zakończeniu ponownego kompilowania indeksu.

W przypadku tabeli z uporządkowanym indeksem ALTER INDEX REORGANIZE klastrowanego magazynu kolumn nie sortuje ponownie danych. 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 Performance tuning with ordered clustered columnstore index (Dostrajanie wydajności z uporządkowanym indeksem klastrowanego magazynu kolumn).

Przyczyny niskiej jakości indeksu magazynu kolumn

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

  1. Wykorzystanie pamięci podczas tworzenia indeksu
  2. Duża liczba operacji DML
  3. Małe lub trudne operacje ładowania
  4. Zbyt wiele partycji

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

Wykorzystanie pamięci podczas tworzenia 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 zapewnienie sesji zapisu w tabelach indeksów magazynu kolumn do jak największej ilości pamięci. Ponieważ istnieje kompromis między pamięcią a współbieżnością, wskazówki dotyczące właściwej 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ć do sesji, która zapisuje dane w tabeli.

Duża liczba operacji DML

Duża liczba operacji DML, które aktualizują i usuwają wiersze, mogą powodować nieefektywność w magazynie kolumn. 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 o nazwie grupy wierszy różnicowych. 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 magazynie różnicowym.

Operacje aktualizacji wsadowej i wstawiania, które przekraczają próg zbiorczy 102 400 wierszy na dystrybucję wyrównaną do partycji, przechodzą 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 magazynu różnicowego i pozostają tam do momentu wstawienia lub zmodyfikowania wystarczających wierszy w celu zamknięcia grupy wierszy lub ponownego skompilowania indeksu.

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. Częściej niż nie dane są znacznie poniżej progu wymaganego do bezpośredniego ładowania do formatu magazynu kolumn.

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 tabela 100 partycji nie zawiera 6 miliardów wierszy, zmniejsz liczbę partycji lub rozważ użycie tabeli stert.

Po załadowaniu tabel z pewnymi danymi wykonaj poniższe kroki, aby zidentyfikować i ponownie skompilować tabele przy użyciu indeksów magazynu kolumn klastrowanych w klastrze.

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 ponownego kompilowania indeksów, zobacz sekcję ALTER INDEX REBUILD w temacie Defragmentacja indeksów magazynu kolumn i ALTER INDEX.

Krok 3. Sprawdź, czy jakość segmentu magazynu kolumn klastra uległa poprawie

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ą bardzo 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).

Następne kroki

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