Projektowanie tabel przy użyciu usługi Synapse SQL w usłudze Azure Synapse Analytics
Ten dokument zawiera kluczowe pojęcia dotyczące projektowania tabel z dedykowaną pulą SQL i bezserwerową pulą SQL.
Bezserwerowa pula SQL to usługa zapytań dla danych w usłudze Data Lake. Nie ma magazynu lokalnego na potrzeby pozyskiwania danych. Dedykowana pula SQL reprezentuje kolekcję zasobów analitycznych, które są aprowizowane podczas korzystania z usługi Synapse SQL. Rozmiar dedykowanej puli SQL jest określany przez jednostki magazynowania danych (DWU).
W poniższej tabeli wymieniono tematy dotyczące dedykowanej puli SQL a bezserwerowej puli SQL:
Temat | dedykowana pula SQL | Bezserwerowa pula SQL |
---|---|---|
Określanie kategorii tabel | Tak | Nie |
Nazwy schematów | Tak | Tak |
Nazwy tabel | Tak | Nie |
Trwałość tabeli | Tak | Nie |
Zwykła tabela | Tak | Nie |
Tabela tymczasowa | Tak | Tak |
Tabela zewnętrzna | Tak | Tak |
Typy danych | Tak | Tak |
Rozproszone tabele | Tak | Nie |
Tabele dystrybuowane przy użyciu skrótu | Tak | Nie |
Zreplikowane tabele | Tak | Nie |
Tabele działania okrężnego | Tak | Nie |
Typowe metody dystrybucji tabel | Tak | Nie |
Partycji | Tak | Tak |
Indeksy magazynu kolumn | Tak | Nie |
Statystyki | Tak | Tak |
Klucz podstawowy i unikatowy klucz | Tak | Nie |
Polecenia służące do tworzenia tabel | Tak | Nie |
Dopasowywanie danych źródłowych do magazynu danych | Tak | Nie |
Nieobsługiwane funkcje tabeli | Tak | Nie |
Zapytania dotyczące rozmiaru tabeli | Tak | Nie |
Określanie kategorii tabel
Schemat gwiazdy organizuje dane w tabelach faktów i wymiarów. Niektóre tabele są używane do integracji lub przemieszczania danych przed przejściem do tabeli faktów lub wymiarów. Podczas projektowania tabeli zdecyduj, czy dane tabeli należą do tabeli faktów, wymiarów czy tabeli integracji. Ta decyzja informuje o odpowiedniej strukturze tabeli i dystrybucji.
Tabele faktów zawierają dane ilościowe, które są często generowane w systemie transakcyjnym, a następnie ładowane do magazynu danych. Na przykład firma detaliczna generuje transakcje sprzedaży codziennie, a następnie ładuje dane do tabeli faktów magazynu danych na potrzeby analizy.
Tabele wymiarów zawierają dane atrybutów, które mogą ulec zmianie, ale zwykle zmieniają się rzadko. Na przykład nazwa i adres klienta są przechowywane w tabeli wymiarów i aktualizowane tylko wtedy, gdy profil klienta ulegnie zmianie. Aby zminimalizować rozmiar dużej tabeli faktów, nazwa i adres klienta nie muszą znajdować się w każdym wierszu tabeli faktów. Zamiast tego tabela faktów i tabela wymiarów mogą udostępniać identyfikator klienta. Zapytanie może łączyć dwie tabele w celu skojarzenia profilu i transakcji klienta.
Tabele integracji zapewniają miejsce na integrowanie lub przemieszczanie danych. Tabelę integracji można utworzyć jako zwykłą tabelę, tabelę zewnętrzną lub tabelę tymczasową. Na przykład można załadować dane do tabeli przejściowej, wykonać przekształcenia na danych w środowisku przejściowym, a następnie wstawić dane do tabeli produkcyjnej.
Nazwy schematów
Schematy są dobrym sposobem grupowania obiektów, które są używane w podobny sposób. Poniższy kod tworzy schemat zdefiniowany przez użytkownika o nazwie wwi.
CREATE SCHEMA wwi;
Nazwy tabel
Jeśli migrujesz wiele baz danych z lokalnego rozwiązania do dedykowanej puli SQL, najlepszym rozwiązaniem jest migrowanie wszystkich tabel faktów, wymiarów i integracji do jednego schematu puli SQL. Na przykład można przechowywać wszystkie tabele w przykładowym magazynie danych WideWorldImportersDW w jednym schemacie o nazwie wwi.
Aby pokazać organizację tabel w dedykowanej puli SQL, można użyć faktów, dim i int jako prefiksów do nazw tabel. W poniższej tabeli przedstawiono niektóre nazwy schematów i tabel wideworldImportersDW.
Tabela WideWorldImportersDW | Typ tabeli | dedykowana pula SQL |
---|---|---|
City (Miasto) | Wymiar | Wwi. DimCity |
Zamówienie | Fact | Wwi. FactOrder |
Trwałość tabeli
Tabele przechowują dane trwale w usłudze Azure Storage, tymczasowo w usłudze Azure Storage lub w magazynie danych zewnętrznym dla magazynu danych.
Zwykła tabela
Zwykła tabela przechowuje dane w usłudze Azure Storage w ramach magazynu danych. Tabela i dane są utrwalane bez względu na to, czy sesja jest otwarta. Poniższy przykład tworzy zwykłą tabelę z dwiema kolumnami.
CREATE TABLE MyTable (col1 int, col2 int );
Tabela tymczasowa
Tabela tymczasowa istnieje tylko przez czas trwania sesji. Możesz użyć tabeli tymczasowej, aby uniemożliwić innym użytkownikom wyświetlanie tymczasowych wyników. Korzystanie z tabel tymczasowych zmniejsza również potrzebę czyszczenia. Tabele tymczasowe korzystają z magazynu lokalnego i, w dedykowanych pulach SQL, mogą oferować szybszą wydajność.
Bezserwerowa pula SQL obsługuje tabele tymczasowe. Jednak jego użycie jest ograniczone, ponieważ można wybrać z tabeli tymczasowej, ale nie można połączyć jej z plikami w magazynie.
Aby uzyskać więcej informacji, zobacz Tabele tymczasowe.
Tabela zewnętrzna
Tabele zewnętrzne wskazują dane znajdujące się w obiekcie blob usługi Azure Storage lub Azure Data Lake Storage.
Zaimportuj dane z tabel zewnętrznych do dedykowanych pul SQL przy użyciu instrukcji CREATE TABLE AS SELECT . Aby zapoznać się z samouczkiem dotyczącym ładowania, zobacz Ładowanie danych z usługi Azure Blob Storage przy użyciu technologii PolyBase.
W przypadku bezserwerowej puli SQL można użyć instrukcji CETAS , aby zapisać wynik zapytania w tabeli zewnętrznej w usłudze Azure Storage.
Typy danych
Dedykowana pula SQL obsługuje najczęściej używane typy danych. Aby uzyskać listę obsługiwanych typów danych, zobacz typy danych w dokumentacji CREATE TABLE w instrukcji CREATE TABLE. Aby uzyskać więcej informacji na temat używania typów danych, zobacz Typy danych.
Rozproszone tabele
Podstawową funkcją dedykowanej puli SQL jest sposób przechowywania i obsługi tabel w różnych dystrybucjach. Dedykowana pula SQL obsługuje trzy metody dystrybucji danych:
- Działanie okrężne (ustawienie domyślne)
- Skrót
- Replikowane
Tabele dystrybuowane przy użyciu skrótu
Tabela rozproszona skrótu dystrybuuje wiersze na podstawie wartości w kolumnie dystrybucji. Tabela rozproszona skrótu została zaprojektowana w celu osiągnięcia wysokiej wydajności zapytań w dużych tabelach. Podczas wybierania kolumny dystrybucji należy wziąć pod uwagę kilka czynników.
Aby uzyskać więcej informacji, zobacz Wskazówki dotyczące projektowania tabel rozproszonych.
Zreplikowane tabele
Replikowana tabela zawiera pełną kopię tabeli dostępnej w każdym węźle obliczeniowym. Zapytania działają szybko w replikowanych tabelach, ponieważ sprzężenia w replikowanych tabelach nie wymagają przenoszenia danych. Jednak replikacja wymaga dodatkowego magazynu i nie jest praktyczna w przypadku dużych tabel.
Aby uzyskać więcej informacji, zobacz Wskazówki dotyczące projektowania replikowanych tabel.
Tabele działania okrężnego
Tabela okrężna dystrybuuje wiersze tabeli równomiernie we wszystkich dystrybucjach. Wiersze są dystrybuowane losowo. Ładowanie danych do tabeli działania okrężnego jest szybkie. Jednak zapytania mogą wymagać większego przenoszenia danych niż inne metody dystrybucji.
Aby uzyskać więcej informacji, zobacz Wskazówki dotyczące projektowania tabel rozproszonych.
Typowe metody dystrybucji tabel
Kategoria tabeli często określa optymalną opcję rozkładu tabel.
Kategoria tabeli | Zalecana opcja dystrybucji |
---|---|
Fact | Użyj dystrybucji skrótów z klastrowanym indeksem magazynu kolumn. Wydajność zwiększa się, gdy dwie tabele skrótów są sprzężone w tej samej kolumnie dystrybucji. |
Wymiar | Użyj replikowanej dla mniejszych tabel. Jeśli tabele są zbyt duże do przechowywania w każdym węźle obliczeniowym, użyj skrótu rozproszonego. |
Przygotowanie | Użyj działania okrężnego dla tabeli przejściowej. Ładowanie za pomocą usługi CTAS jest szybkie. Gdy dane są w tabeli przejściowej, użyj polecenia INSERT... WYBIERZ, aby przenieść dane do tabel produkcyjnych. |
Partycje
W dedykowanych pulach SQL partycjonowana tabela przechowuje i wykonuje operacje na wierszach tabeli zgodnie z zakresami danych. Na przykład tabela może być partycjonowana według dnia, miesiąca lub roku. Wydajność zapytań można poprawić poprzez eliminację partycji, co ogranicza skanowanie zapytań do danych w ramach partycji.
Dane można również przechowywać za pomocą przełączania partycji. Ponieważ dane w dedykowanej puli SQL są już dystrybuowane, zbyt wiele partycji może spowolnić wydajność zapytań. Aby uzyskać więcej informacji, zobacz Partitioning guidance (Wskazówki dotyczące partycjonowania).
Porada
Podczas przełączania partycji na partycje tabeli, które nie są puste, rozważ użycie opcji TRUNCATE_TARGET w instrukcji ALTER TABLE , jeśli istniejące dane mają zostać obcięte.
Poniższy kod przełącza przekształcone dane dzienne na partycję SalesFact i zastępuje wszystkie istniejące dane.
ALTER TABLE SalesFact_DailyFinalLoad SWITCH PARTITION 256 TO SalesFact PARTITION 256 WITH (TRUNCATE_TARGET = ON);
W bezserwerowej puli SQL można ograniczyć pliki/foldery (partycje), które będą odczytywane przez zapytanie. Partycjonowanie według ścieżki jest obsługiwane przy użyciu funkcji filepath i fileinfo opisanych w artykule Wykonywanie zapytań dotyczących plików magazynu. Poniższy przykład odczytuje folder z danymi w roku 2017:
SELECT
nyc.filepath(1) AS [year],
payment_type,
SUM(fare_amount) AS fare_total
FROM
OPENROWSET(
BULK 'https://sqlondemandstorage.blob.core.windows.net/parquet/taxi/year=*/month=*/*.parquet',
FORMAT='PARQUET'
) AS nyc
WHERE
nyc.filepath(1) = 2017
GROUP BY
nyc.filepath(1),
payment_type
ORDER BY
nyc.filepath(1),
payment_type
Indeksy magazynu kolumn
Domyślnie dedykowana pula SQL przechowuje tabelę jako indeks klastrowanego magazynu kolumn. Ta forma magazynu danych zapewnia wysoką kompresję danych i wydajność zapytań w dużych tabelach. Indeks klastrowanego magazynu kolumn jest zwykle najlepszym wyborem, ale w niektórych przypadkach indeks klastrowany lub stertę jest odpowiednią strukturą magazynu.
Porada
Tabela sterty może być szczególnie przydatna do ładowania danych przejściowych, takich jak tabela przejściowa, która jest przekształcana w końcową tabelę.
Aby uzyskać listę funkcji magazynu kolumn, zobacz Co nowego dla indeksów magazynu kolumn. Aby zwiększyć wydajność indeksu magazynu kolumn, zobacz Maksymalizowanie jakości grup wierszy dla indeksów magazynu kolumn.
Statystyki
Optymalizator zapytań używa statystyk na poziomie kolumny podczas tworzenia planu do wykonywania zapytania. Aby zwiększyć wydajność zapytań, ważne jest, aby statystyki dotyczące poszczególnych kolumn, zwłaszcza kolumn używanych w sprzężeniach zapytań. Usługa Synapse SQL obsługuje automatyczne tworzenie statystyk.
Aktualizacja statystyczna nie jest automatycznie aktualizowana. Zaktualizuj statystyki po dodaniu lub zmianie liczby wierszy. Na przykład zaktualizuj statystyki po załadowaniu. Dodatkowe informacje znajdują się w artykule Wskazówki dotyczące statystyk .
Klucz podstawowy i unikatowy klucz
W przypadku dedykowanej puli SQL klucz PODSTAWOWY jest obsługiwany tylko wtedy, gdy są używane zarówno elementy NONCLUSTERED, jak i NOT ENFORCED. Ograniczenie UNIQUE jest obsługiwane tylko wtedy, gdy nie jest używana wartość WYMUSZAna. Aby uzyskać więcej informacji, zobacz dedykowany artykuł dotyczący ograniczeń tabeli puli SQL .
Polecenia służące do tworzenia tabel
W przypadku dedykowanej puli SQL można utworzyć tabelę jako nową pustą tabelę. Możesz również utworzyć i wypełnić tabelę wynikami instrukcji select. Poniżej przedstawiono polecenia języka T-SQL służące do tworzenia tabeli.
T-SQL, instrukcja | Opis |
---|---|
CREATE TABLE | Tworzy pustą tabelę, definiując wszystkie kolumny i opcje tabeli. |
TWORZENIE TABELI ZEWNĘTRZNEJ | Tworzy tabelę zewnętrzną. Definicja tabeli jest przechowywana w dedykowanej puli SQL. Dane tabeli są przechowywane w usłudze Azure Blob Storage lub Azure Data Lake Storage. |
CREATE TABLE AS SELECT | Wypełnia nową tabelę wynikami instrukcji select. Kolumny tabeli i typy danych są oparte na wynikach instrukcji select. Aby zaimportować dane, ta instrukcja może wybrać z tabeli zewnętrznej. |
UTWÓRZ TABELĘ ZEWNĘTRZNĄ JAKO WYBIERZ | Tworzy nową tabelę zewnętrzną przez wyeksportowanie wyników instrukcji select do lokalizacji zewnętrznej. Lokalizacja to usługa Azure Blob Storage lub Azure Data Lake Storage. |
Dopasowywanie danych źródłowych do magazynu danych
Dedykowane tabele puli SQL są wypełniane przez ładowanie danych z innego źródła danych. Aby osiągnąć pomyślne ładowanie, liczba i typy danych kolumn w danych źródłowych muszą być zgodne z definicją tabeli w magazynie danych.
Uwaga
Pobieranie danych do wyrównania może być najtrudniejszą częścią projektowania tabel.
Jeśli dane pochodzą z wielu magazynów danych, możesz przenieść dane do magazynu danych i zapisać je w tabeli integracji. Gdy dane są w tabeli integracji, możesz użyć możliwości dedykowanej puli SQL do zaimplementowania operacji przekształcania. Po przygotowaniu danych można je wstawić do tabel produkcyjnych.
Nieobsługiwane funkcje tabeli
Dedykowana pula SQL obsługuje wiele funkcji tabeli oferowanych przez inne bazy danych, ale nie wszystkie. Poniższa lista zawiera niektóre funkcje tabeli, które nie są obsługiwane w dedykowanej puli SQL.
- Klucz obcy, sprawdź ograniczenia tabeli
- Kolumny obliczane
- Indeksowane widoki
- Sequence
- Kolumny rozrzedłe
- Klucze zastępcze, implementowanie za pomocą tożsamości
- Synonimy
- Wyzwalacze
- Indeksy unikatowe
- Typy zdefiniowane przez użytkownika
Zapytania dotyczące rozmiaru tabeli
W dedykowanej puli SQL jednym z prostych sposobów identyfikowania miejsca i wierszy używanych przez tabelę w każdej z 60 dystrybucji jest użycie PDW_SHOWSPACEUSED DBCC.
DBCC PDW_SHOWSPACEUSED('dbo.FactInternetSales');
Należy pamiętać, że używanie poleceń DBCC może być dość ograniczane. Dynamiczne widoki zarządzania (DMV) pokazują więcej szczegółów niż polecenia DBCC. Zacznij od utworzenia poniższego widoku.
CREATE VIEW dbo.vTableSizes
AS
WITH base
AS
(
SELECT
GETDATE() AS [execution_time]
, DB_NAME() AS [database_name]
, s.name AS [schema_name]
, t.name AS [table_name]
, QUOTENAME(s.name)+'.'+QUOTENAME(t.name) AS [two_part_name]
, nt.[name] AS [node_table_name]
, ROW_NUMBER() OVER(PARTITION BY nt.[name] ORDER BY (SELECT NULL)) AS [node_table_name_seq]
, tp.[distribution_policy_desc] AS [distribution_policy_name]
, c.[name] AS [distribution_column]
, nt.[distribution_id] AS [distribution_id]
, i.[type] AS [index_type]
, i.[type_desc] AS [index_type_desc]
, nt.[pdw_node_id] AS [pdw_node_id]
, pn.[type] AS [pdw_node_type]
, pn.[name] AS [pdw_node_name]
, di.name AS [dist_name]
, di.position AS [dist_position]
, nps.[partition_number] AS [partition_nmbr]
, nps.[reserved_page_count] AS [reserved_space_page_count]
, nps.[reserved_page_count] - nps.[used_page_count] AS [unused_space_page_count]
, nps.[in_row_data_page_count]
+ nps.[row_overflow_used_page_count]
+ nps.[lob_used_page_count] AS [data_space_page_count]
, nps.[reserved_page_count]
- (nps.[reserved_page_count] - nps.[used_page_count])
- ([in_row_data_page_count]
+ [row_overflow_used_page_count]+[lob_used_page_count]) AS [index_space_page_count]
, nps.[row_count] AS [row_count]
from
sys.schemas s
INNER JOIN sys.tables t
ON s.[schema_id] = t.[schema_id]
INNER JOIN sys.indexes i
ON t.[object_id] = i.[object_id]
AND i.[index_id] <= 1
INNER JOIN sys.pdw_table_distribution_properties tp
ON t.[object_id] = tp.[object_id]
INNER JOIN sys.pdw_table_mappings tm
ON t.[object_id] = tm.[object_id]
INNER JOIN sys.pdw_nodes_tables nt
ON tm.[physical_name] = nt.[name]
INNER JOIN sys.dm_pdw_nodes pn
ON nt.[pdw_node_id] = pn.[pdw_node_id]
INNER JOIN sys.pdw_distributions di
ON nt.[distribution_id] = di.[distribution_id]
INNER JOIN sys.dm_pdw_nodes_db_partition_stats nps
ON nt.[object_id] = nps.[object_id]
AND nt.[pdw_node_id] = nps.[pdw_node_id]
AND nt.[distribution_id] = nps.[distribution_id]
LEFT OUTER JOIN (select * from sys.pdw_column_distribution_properties where distribution_ordinal = 1) cdp
ON t.[object_id] = cdp.[object_id]
LEFT OUTER JOIN sys.columns c
ON cdp.[object_id] = c.[object_id]
AND cdp.[column_id] = c.[column_id]
WHERE pn.[type] = 'COMPUTE'
)
, size
AS
(
SELECT
[execution_time]
, [database_name]
, [schema_name]
, [table_name]
, [two_part_name]
, [node_table_name]
, [node_table_name_seq]
, [distribution_policy_name]
, [distribution_column]
, [distribution_id]
, [index_type]
, [index_type_desc]
, [pdw_node_id]
, [pdw_node_type]
, [pdw_node_name]
, [dist_name]
, [dist_position]
, [partition_nmbr]
, [reserved_space_page_count]
, [unused_space_page_count]
, [data_space_page_count]
, [index_space_page_count]
, [row_count]
, ([reserved_space_page_count] * 8.0) AS [reserved_space_KB]
, ([reserved_space_page_count] * 8.0)/1000 AS [reserved_space_MB]
, ([reserved_space_page_count] * 8.0)/1000000 AS [reserved_space_GB]
, ([reserved_space_page_count] * 8.0)/1000000000 AS [reserved_space_TB]
, ([unused_space_page_count] * 8.0) AS [unused_space_KB]
, ([unused_space_page_count] * 8.0)/1000 AS [unused_space_MB]
, ([unused_space_page_count] * 8.0)/1000000 AS [unused_space_GB]
, ([unused_space_page_count] * 8.0)/1000000000 AS [unused_space_TB]
, ([data_space_page_count] * 8.0) AS [data_space_KB]
, ([data_space_page_count] * 8.0)/1000 AS [data_space_MB]
, ([data_space_page_count] * 8.0)/1000000 AS [data_space_GB]
, ([data_space_page_count] * 8.0)/1000000000 AS [data_space_TB]
, ([index_space_page_count] * 8.0) AS [index_space_KB]
, ([index_space_page_count] * 8.0)/1000 AS [index_space_MB]
, ([index_space_page_count] * 8.0)/1000000 AS [index_space_GB]
, ([index_space_page_count] * 8.0)/1000000000 AS [index_space_TB]
FROM base
)
SELECT *
FROM size
;
Podsumowanie obszaru tabeli
To zapytanie zwraca wiersze i spację według tabeli. Podsumowanie obszaru tabeli pozwala zobaczyć, które tabele są największymi tabelami. Zobaczysz również, czy są one działaniem okrężnym, replikowanym, czy rozproszonym skrótem. W przypadku tabel rozproszonych skrótami zapytanie wyświetla kolumnę dystrybucji.
SELECT
database_name
, schema_name
, table_name
, distribution_policy_name
, distribution_column
, index_type_desc
, COUNT(distinct partition_nmbr) as nbr_partitions
, SUM(row_count) as table_row_count
, SUM(reserved_space_GB) as table_reserved_space_GB
, SUM(data_space_GB) as table_data_space_GB
, SUM(index_space_GB) as table_index_space_GB
, SUM(unused_space_GB) as table_unused_space_GB
FROM
dbo.vTableSizes
GROUP BY
database_name
, schema_name
, table_name
, distribution_policy_name
, distribution_column
, index_type_desc
ORDER BY
table_reserved_space_GB desc
;
Odstęp tabeli według typu dystrybucji
SELECT
distribution_policy_name
, SUM(row_count) as table_type_row_count
, SUM(reserved_space_GB) as table_type_reserved_space_GB
, SUM(data_space_GB) as table_type_data_space_GB
, SUM(index_space_GB) as table_type_index_space_GB
, SUM(unused_space_GB) as table_type_unused_space_GB
FROM dbo.vTableSizes
GROUP BY distribution_policy_name
;
Obszar tabeli według typu indeksu
SELECT
index_type_desc
, SUM(row_count) as table_type_row_count
, SUM(reserved_space_GB) as table_type_reserved_space_GB
, SUM(data_space_GB) as table_type_data_space_GB
, SUM(index_space_GB) as table_type_index_space_GB
, SUM(unused_space_GB) as table_type_unused_space_GB
FROM dbo.vTableSizes
GROUP BY index_type_desc
;
Podsumowanie obszaru dystrybucji
SELECT
distribution_id
, SUM(row_count) as total_node_distribution_row_count
, SUM(reserved_space_MB) as total_node_distribution_reserved_space_MB
, SUM(data_space_MB) as total_node_distribution_data_space_MB
, SUM(index_space_MB) as total_node_distribution_index_space_MB
, SUM(unused_space_MB) as total_node_distribution_unused_space_MB
FROM dbo.vTableSizes
GROUP BY distribution_id
ORDER BY distribution_id
;
Następne kroki
Po utworzeniu tabel dla magazynu danych następnym krokiem jest załadowanie danych do tabeli. Aby zapoznać się z samouczkiem dotyczącym ładowania, zobacz Ładowanie danych do dedykowanej puli SQL.