Táblák tervezése dedikált SQL-készlet használatával a Azure Synapse Analytics

Tipp

Microsoft Fabric Data Warehouse egy nagyvállalati szintű relációs raktár egy Data Lake-alaprendszeren, jövőre kész architektúrával, beépített AI-vel és új funkciókkal. Ha még nem ismerkedik adattárházzal, kezdje a Fabric Data Warehouse. A meglévő dedikált SQL-készlet számítási feladatai frissíthetők Fabric az adatelemzés, a valós idejű elemzés és a jelentéskészítés új képességeinek eléréséhez.

Ez a cikk a táblák dedikált SQL-készletben való tervezésének legfontosabb bevezető fogalmait ismerteti.

Táblakategória meghatározása

A csillagséma tény- és dimenziótáblákba rendezi az adatokat. Egyes táblákat az integrációhoz vagy az adatok átmeneti tárolásához használunk, mielőtt egy tény- vagy dimenziótáblára kerülnénk. Táblázat tervezésekor döntse el, hogy a tábla adatai tény-, dimenzió- vagy integrációs táblába tartoznak-e. Ez a döntés meghatározza a megfelelő táblaszerkezetet és -eloszlást.

  • A ténytáblák olyan mennyiségi adatokat tartalmaznak, amelyek általában tranzakciós rendszerben jönnek létre, majd betölthetők a dedikált SQL-készletbe. Egy kiskereskedelmi vállalat például naponta generál értékesítési tranzakciókat, majd betölti az adatokat egy dedikált SQL-készlet ténytáblájába elemzés céljából.

  • A dimenziótáblák olyan attribútumadatokat tartalmaznak, amelyek változhatnak, de általában ritkán változnak. Az ügyfél neve és címe például egy dimenziótáblában van tárolva, és csak akkor frissül, ha az ügyfél profilja megváltozik. A nagy ténytáblák méretének minimalizálásához az ügyfél nevének és címének nem kell egy ténytábla minden sorában lennie. Ehelyett a ténytábla és a dimenziótábla megoszthat egy ügyfél-azonosítót. A lekérdezések összekapcsolhatják a két táblát az ügyfél profiljának és tranzakcióinak társításához.

  • Az integrációs táblák helyet biztosítanak az adatok integrálásához vagy átmeneti tárolásához. Az integrációs táblákat normál, külső vagy ideiglenes táblaként is létrehozhatja. Betöltheti például az adatokat egy átmeneti táblába, átalakításokat hajthat végre az előállításban lévő adatokon, majd beszúrhatja az adatokat egy produkciós táblába.

Séma- és táblanevek

A sémák jól csoportosítják a táblákat, amelyeket hasonló módon használnak együtt. Ha több adatbázist migrál egy helyszíni megoldásból egy dedikált SQL-készletbe, a legjobb megoldás, ha az összes tény-, dimenzió- és integrációs táblát egy dedikált SQL-készlet egy sémájára migrálja.

Az összes táblát például a WideWorldImportersDW-minta dedikált SQL-készletében tárolhatja egy úgynevezett wwisémában. Az alábbi kód létrehoz egy felhasználó által definiált sémát nevű wwi.

CREATE SCHEMA wwi;

Ha meg szeretné jeleníteni a táblák rendszerezését a dedikált SQL-készletben, a táblanevek előtagjaként használhatja a tény, a dim és a int elemet. Az alábbi táblázat néhány sémát és táblanevet WideWorldImportersDWmutat be.

WideWorldImportersDW tábla Táblázat típusa Dedikált SQL-készlet
Város Dimenzió wwi.DimCity
Rendelés Tény wwi.FactOrder

Táblamegőrzés

A táblák véglegesen vagy ideiglenesen az Azure Storage-ben, vagy külső adattárban a dedikált SQL-készlet mellett tárolják az adatokat.

Reguláris táblázat

Egy normál tábla az adatokat az Azure Storage-ban tárolja dedikált SQL-készlet részeként. A tábla és az adatok attól függetlenül megmaradnak, hogy egy munkamenet meg van-e nyitva. Az alábbi példa egy normál táblát hoz létre két oszlopból.

CREATE TABLE MyTable (col1 int, col2 int );  

Ideiglenes tábla

Ideiglenes tábla csak a munkamenet idejére létezik. Ideiglenes táblával megakadályozhatja, hogy más felhasználók is láthassák az ideiglenes eredményeket, és hogy csökkentse a törlés szükségességét.

Az ideiglenes táblák helyi tárolót használnak a gyors teljesítmény érdekében. További információ: Ideiglenes táblák.

Külső tábla

Egy külső tábla Azure Storage blobban vagy Azure Data Lake Store-ban található adatokra mutat. Ha a CREATE TABLE AS SELECT utasítással használja, a külső tábla kiválasztásával adatokat importál a dedikált SQL-készletbe.

Ezért a külső táblák hasznosak az adatok betöltéséhez. A betöltési oktatóanyagot a Az adatok Azure blobtárolóból való betöltéséhez a PolyBase használata című témakörben talál.

Adattípusok

A dedikált SQL-készlet támogatja a leggyakrabban használt adattípusokat. A támogatott adattípusok listáját a CREATE TABLE utasítás CREATE TABLE hivatkozásában találja. Az adattípusok használatáról további információt az Adattípusok című témakörben talál.

Elosztott táblák

A dedikált SQL-készlet egyik alapvető funkciója, hogy hogyan tárolhatja és kezelheti a táblákat a disztribúciók között. A dedikált SQL-készlet három módszert támogat az adatok elosztásához: ciklikus időszeletelés (alapértelmezett), kivonatolás és replikálás.

Hash-alapú elosztott táblák

A kivonatelosztott táblák a terjesztési oszlopban lévő érték alapján osztják el a sorokat. A kivonatelosztott táblákat úgy tervezték, hogy nagy teljesítményű lekérdezéseket érjenek el nagy táblákon. A terjesztési oszlop kiválasztásakor több tényezőt is figyelembe kell venni.

További információ: Tervezési útmutató elosztott táblákhoz.

Replikált táblák

A replikált táblákban minden számítási csomóponton elérhető a tábla teljes másolata. A lekérdezések gyorsan futnak a replikált táblákon, mivel a replikált táblák illesztése nem igényel adatáthelyezést. A replikációhoz azonban extra tárhelyre van szükség, és nagy táblák esetében nem praktikus.

További információ: Tervezési útmutató replikált táblákhoz.

Körforgásos táblák

A körforgó táblázat egyenletesen osztja el a táblázat sorait az összes eloszlások között. A sorok véletlenszerűen vannak elosztva. Az adatok körkörös táblába való betöltése gyors. Ne feledje, hogy a lekérdezések több adatáthelyezést igényelhetnek, mint a többi terjesztési módszer.

További információ: Tervezési útmutató elosztott táblákhoz.

Táblák gyakori terjesztési módszerei

A táblakategória gyakran meghatározza, hogy melyik lehetőséget válassza a tábla terjesztéséhez.

Táblakategória Ajánlott terjesztési lehetőség
Tény Hash-distribution használata fürtözött oszlopcentrikus indexekkel. A teljesítmény akkor javul, ha két kivonattábla csatlakozik ugyanazon a terjesztési oszlopon.
Dimenzió Használjon replikáltat kisebb táblák esetében. Ha a táblák túl nagyok az egyes számítási csomópontokon való tároláshoz, használjon hash-alapú elosztást.
Tesztkörnyezet Az előkészítési táblázathoz használjon körkörös elosztást. A CTAS-sel történő terhelés gyors. Miután az adatok bekerültek az előkészítési táblába, használja az INSERT...SELECT parancsot az adatok éles táblákba való áthelyezéséhez.

Megjegyzés

A számítási feladatok alapján használható legjobb táblázatterjesztési stratégiával kapcsolatos javaslatokért tekintse meg az Azure Synapse SQL Distribution Advisor.

Táblapartíciók

A particionált táblák adattartományok szerint tárolják és hajtják végre a műveleteket a táblasorokon. Egy tábla például nap, hónap vagy év szerint particionálható. A partíciók eltávolításával javíthatja a lekérdezési teljesítményt, ami a partíción belüli adatokra korlátozza a lekérdezések vizsgálatát. Az adatokat partícióváltással is karbantarthatja. Mivel az SQL-készlet adatai már elosztottak, a túl sok partíció lelassíthatja a lekérdezési teljesítményt. További információ: Particionálási útmutató. Ha partíciócsere történik nem üres táblapartíciókra, fontolja meg az ALTER TABLE utasításban a TRUNCATE_TARGET opció használatát, ha a meglévő adatokat csonkolni kell. Az alábbi kód a napi átalakított adatokat beírja a SalesFact táblába, felülírva minden meglévő adatot.

ALTER TABLE SalesFact_DailyFinalLoad SWITCH PARTITION 256 TO SalesFact PARTITION 256 WITH (TRUNCATE_TARGET = ON);  

Oszlopos adattárolású indexek

Alapértelmezés szerint a dedikált SQL-tár fürtözött oszlopos tárolási indexként tárol egy táblát. Az adattárolás ezen formája nagy méretű táblákon magas adattömörítési és lekérdezési teljesítményt biztosít.

A fürtözött oszlop tárindex általában a legjobb választás, de bizonyos esetekben egy fürtözött index vagy egy halom a megfelelő tárolási struktúra.

Tipp

A halomtábla különösen hasznos lehet átmeneti adatok betöltéséhez, például egy átmeneti táblához, amely végső táblává alakul át.

Az oszlopcentrikus funkciók listáját az oszlopcentrikus indexek újdonságai című témakörben találja. Az oszlopcentrikus index teljesítményének javításához tekintse meg az oszlopcentrikus indexek sorcsoportminőségének maximalizálása című témakört.

statisztika

A lekérdezésoptimalizáló oszlopszintű statisztikákat használ, amikor létrehozza a lekérdezés végrehajtásához szükséges tervet.

A lekérdezési teljesítmény javítása érdekében fontos, hogy az egyes oszlopokra, különösen a lekérdezési illesztésekben használt oszlopokra vonatkozó statisztikák rendelkezzenek. A statisztikák létrehozása automatikusan megtörténik.

A statisztikák frissítése nem történik meg automatikusan. Jelentős számú sor hozzáadása vagy módosítása után frissítse a statisztikákat. Például a terhelés utáni statisztikák frissítése. További információ: Statisztika – útmutató.

Elsődleges kulcs és egyedi kulcs

Az ELSŐDLEGES KULCS csak akkor támogatott, ha a NEMCLUSTERED és a NOT ENFORCED is használatban van. AZ EGYEDI korlátozás csak a NOT ENFORCED használatával támogatott. Ellenőrizze a dedikált SQL-készlet tábláinak korlátozásait.

Parancsok táblák létrehozásához

Új üres táblaként is létrehozhat táblát. Emellett létrehozhat és feltölthet egy táblázatot egy kijelölési utasítás eredményeivel. A táblázat létrehozásához a következő T-SQL-parancsok tartoznak.

T-SQL-utasítás Description
CREATE TABLE Üres táblát hoz létre az összes táblaoszlop és beállítás megadásával.
KÜLSŐ TÁBLA LÉTREHOZÁSA Létrehoz egy külső táblát. A tábla definíciója dedikált SQL-készletben van tárolva. A táblaadatok tárolása Azure Blob Storage-ban vagy Azure Data Lake Store-ban történik.
`CREATE TABLE AS SELECT` Megtölt egy új táblát egy SELECT utasítás eredményével. A táblaoszlopok és adattípusok a select utasítás eredményein alapulnak. Az adatok importálásához ez az utasítás kiválasztható egy külső táblából.
Külső tábla létrehozása select utasítással Új külső táblát hoz létre egy kiválasztási utasítás eredményeinek külső helyre való exportálásával. A hely vagy Azure Blob Storage vagy Azure Data Lake Store.

Forrásadatok igazítása dedikált SQL-készlethez

A dedikált SQL-készlettáblák feltöltése egy másik adatforrásból származó adatok betöltésével lehetséges. A sikeres betöltés végrehajtásához a forrásadatok oszlopainak számának és adattípusainak egyezőnek kell lenniük a dedikált SQL-készlet tábladefiníciójával. Az adatok igazítása lehet a táblák tervezésének legnehezebb része.

Ha az adatok több adattárból származnak, betölti az adatokat a dedikált SQL-készletbe, és egy integrációs táblában tárolja. Miután az adatok az integrációs táblában szerepelnek, a dedikált SQL-készlet erejével átalakítási műveleteket hajthat végre. Az adatok előkészítése után beillesztheti azokat a produkciós táblákba.

Nem támogatott táblafunkciók

A dedikált SQL-készlet számos, de nem az összes táblafunkciót támogatja, amelyeket más adatbázisok kínálnak. Az alábbi lista néhány olyan táblafunkciót mutat be, amelyek nem támogatottak a dedikált SQL-készletben:

Táblaméret-lekérdezések

Megjegyzés

Az ebben a szakaszban található lekérdezésekből származó pontos számok érdekében győződjön meg arról, hogy az indexkarbantartás rendszeresen és nagy adatváltozások után történik.

A 60 eloszlás mindegyikében egy táblázat által felhasznált tér és sorok azonosításának egyik egyszerű módja a DBCC PDW_SHOWSPACEUSED használata.

DBCC PDW_SHOWSPACEUSED('dbo.FactInternetSales');

A DBCC-parancsok használata azonban meglehetősen korlátozott lehet. A dinamikus felügyeleti nézetek (DMV-k) részletesebben jelennek meg, mint a DBCC-parancsok. Először hozza létre ezt a nézetet:

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]
    AND i.[index_id] = nps.[index_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
;

Táblázatterület összegzése

Ez a lekérdezés tábla szerint adja vissza a sorokat és a szóközöket. Így láthatja, hogy mely táblák a legnagyobb táblák, és hogy körkörös, replikált vagy hash-alapú elosztású táblákról van-e szó. Kivonatolt táblák esetén a lekérdezés a terjesztési oszlopot jeleníti meg.

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
;

Táblatér eloszlástípus szerint

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
;

Táblatér indextípus szerint

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
;

Terjesztési terület összegzése

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
;

A dedikált SQL-készlet tábláinak létrehozása után a következő lépés az adatok betöltése a táblába. Betöltési oktatóanyagért tekintse meg Adatok betöltése dedikált SQL-készletbe és tekintse át a Adatbetöltési stratégiákat a dedikált SQL-készlethez Azure Synapse Analytics.