Tabele tymczasowe w usłudze Synapse SQL

Ten artykuł zawiera podstawowe wskazówki dotyczące używania tabel tymczasowych i wyróżnia zasady tabel tymczasowych na poziomie sesji w usłudze Synapse SQL.

Zarówno dedykowana pula SQL, jak i zasoby bezserwerowej puli SQL mogą korzystać z tabel tymczasowych. Bezserwerowa pula SQL ma ograniczenia omówione na końcu tego artykułu.

Tabele tymczasowe

Tabele tymczasowe są przydatne podczas przetwarzania danych, zwłaszcza podczas przekształcania, gdy wyniki pośrednie są przejściowe. W przypadku usługi Synapse SQL tabele tymczasowe istnieją na poziomie sesji. Są one widoczne tylko dla sesji, w której zostały utworzone. W związku z tym są one automatycznie porzucane po zakończeniu tej sesji.

Tabele tymczasowe w dedykowanej puli SQL

W dedykowanym zasobie puli SQL tabele tymczasowe oferują korzyść wydajności, ponieważ ich wyniki są zapisywane w magazynie lokalnym, a nie w magazynie zdalnym.

Tworzenie tabeli tymczasowej

Tabele tymczasowe są tworzone przez prefiks nazwy tabeli z .# Przykład:

CREATE TABLE #stats_ddl
(
    [schema_name]        NVARCHAR(128) NOT NULL
,    [table_name]            NVARCHAR(128) NOT NULL
,    [stats_name]            NVARCHAR(128) NOT NULL
,    [stats_is_filtered]     BIT           NOT NULL
,    [seq_nmbr]              BIGINT        NOT NULL
,    [two_part_name]         NVARCHAR(260) NOT NULL
,    [three_part_name]       NVARCHAR(400) NOT NULL
)
WITH
(
    DISTRIBUTION = HASH([seq_nmbr])
,    HEAP
)

Tabele tymczasowe można również utworzyć CTAS przy użyciu dokładnie tego samego podejścia:

CREATE TABLE #stats_ddl
WITH
(
    DISTRIBUTION = HASH([seq_nmbr])
,    HEAP
)
AS
(
SELECT
        sm.[name]                                                                AS [schema_name]
,        tb.[name]                                                                AS [table_name]
,        st.[name]                                                                AS [stats_name]
,        st.[has_filter]                                                            AS [stats_is_filtered]
,       ROW_NUMBER()
        OVER(ORDER BY (SELECT NULL))                                            AS [seq_nmbr]
,                                 QUOTENAME(sm.[name])+'.'+QUOTENAME(tb.[name])  AS [two_part_name]
,        QUOTENAME(DB_NAME())+'.'+QUOTENAME(sm.[name])+'.'+QUOTENAME(tb.[name])  AS [three_part_name]
FROM    sys.objects            AS ob
JOIN    sys.stats            AS st    ON    ob.[object_id]        = st.[object_id]
JOIN    sys.stats_columns    AS sc    ON    st.[stats_id]        = sc.[stats_id]
                                    AND st.[object_id]        = sc.[object_id]
JOIN    sys.columns            AS co    ON    sc.[column_id]        = co.[column_id]
                                    AND    sc.[object_id]        = co.[object_id]
JOIN    sys.tables            AS tb    ON    co.[object_id]        = tb.[object_id]
JOIN    sys.schemas            AS sm    ON    tb.[schema_id]        = sm.[schema_id]
WHERE    1=1
AND        st.[user_created]   = 1
GROUP BY
        sm.[name]
,        tb.[name]
,        st.[name]
,        st.[filter_definition]
,        st.[has_filter]
)
;

Uwaga

CTAS jest zaawansowanym poleceniem i ma dodatkową zaletę efektywnego korzystania z przestrzeni dziennika transakcji.

Usuwanie tabel tymczasowych

Po utworzeniu nowej sesji nie powinny istnieć tabele tymczasowe. Jeśli jednak wywołujesz tę samą procedurę składowaną, która tworzy tymczasową nazwę o tej samej nazwie, aby upewnić się, że CREATE TABLE instrukcje zakończyły się pomyślnie, użyj prostego sprawdzania wstępnego istnienia z poleceniem DROP:

IF OBJECT_ID('tempdb..#stats_ddl') IS NOT NULL
BEGIN
    DROP TABLE #stats_ddl
END

Aby zapewnić spójność kodowania, dobrym rozwiązaniem jest użycie tego wzorca zarówno dla tabel, jak i tabel tymczasowych. Dobrym pomysłem DROP TABLE jest również usunięcie tabel tymczasowych po zakończeniu pracy z nimi.

W przypadku opracowywania procedur składowanych często są wyświetlane polecenia upuszczania połączone na końcu procedury w celu zapewnienia, że te obiekty są czyszczone.

DROP TABLE #stats_ddl

Modularyzacja kodu

Tabele tymczasowe mogą być używane w dowolnym miejscu w sesji użytkownika. Ta funkcja może zostać wykorzystana w celu ułatwienia modularyzacji kodu aplikacji. Aby to zademonstrować, poniższa procedura składowana generuje kod DDL w celu zaktualizowania wszystkich statystyk w bazie danych według nazwy statystyki:

CREATE PROCEDURE    [dbo].[prc_sqldw_update_stats]
(   @update_type    tinyint -- 1 default 2 fullscan 3 sample 4 resample
    ,@sample_pct     tinyint
)
AS

IF @update_type NOT IN (1,2,3,4)
BEGIN;
    THROW 151000,'Invalid value for @update_type parameter. Valid range 1 (default), 2 (fullscan), 3 (sample) or 4 (resample).',1;
END;

IF @sample_pct IS NULL
BEGIN;
    SET @sample_pct = 20;
END;

IF OBJECT_ID('tempdb..#stats_ddl') IS NOT NULL
BEGIN
    DROP TABLE #stats_ddl
END

CREATE TABLE #stats_ddl
WITH
(
    DISTRIBUTION = HASH([seq_nmbr])
)
AS
(
SELECT
        sm.[name]                                                                AS [schema_name]
,        tb.[name]                                                                AS [table_name]
,        st.[name]                                                                AS [stats_name]
,        st.[has_filter]                                                            AS [stats_is_filtered]
,       ROW_NUMBER()
        OVER(ORDER BY (SELECT NULL))                                            AS [seq_nmbr]
,                                 QUOTENAME(sm.[name])+'.'+QUOTENAME(tb.[name])  AS [two_part_name]
,        QUOTENAME(DB_NAME())+'.'+QUOTENAME(sm.[name])+'.'+QUOTENAME(tb.[name])  AS [three_part_name]
FROM    sys.objects            AS ob
JOIN    sys.stats            AS st    ON    ob.[object_id]        = st.[object_id]
JOIN    sys.stats_columns    AS sc    ON    st.[stats_id]        = sc.[stats_id]
                                    AND st.[object_id]        = sc.[object_id]
JOIN    sys.columns            AS co    ON    sc.[column_id]        = co.[column_id]
                                    AND    sc.[object_id]        = co.[object_id]
JOIN    sys.tables            AS tb    ON    co.[object_id]        = tb.[object_id]
JOIN    sys.schemas            AS sm    ON    tb.[schema_id]        = sm.[schema_id]
WHERE    1=1
AND        st.[user_created]   = 1
GROUP BY
        sm.[name]
,        tb.[name]
,        st.[name]
,        st.[filter_definition]
,        st.[has_filter]
)
SELECT
    CASE @update_type
    WHEN 1
    THEN 'UPDATE STATISTICS '+[two_part_name]+'('+[stats_name]+');'
    WHEN 2
    THEN 'UPDATE STATISTICS '+[two_part_name]+'('+[stats_name]+') WITH FULLSCAN;'
    WHEN 3
    THEN 'UPDATE STATISTICS '+[two_part_name]+'('+[stats_name]+') WITH SAMPLE '+CAST(@sample_pct AS VARCHAR(20))+' PERCENT;'
    WHEN 4
    THEN 'UPDATE STATISTICS '+[two_part_name]+'('+[stats_name]+') WITH RESAMPLE;'
    END AS [update_stats_ddl]
,   [seq_nmbr]
FROM    #stats_ddl
;
GO

Na tym etapie jedyną akcją, która wystąpiła, jest utworzenie procedury składowanej, która generuje #stats_ddl tabeli tymczasowej. Procedura składowana spada #stats_ddl, jeśli już istnieje. Ten spadek gwarantuje, że nie powiedzie się, jeśli zostanie uruchomiony więcej niż raz w ramach sesji.

Ponieważ nie DROP TABLE ma elementu na końcu procedury składowanej, po zakończeniu procedury składowanej utworzona tabela pozostaje i można ją odczytać poza procedurą składowaną.

W przeciwieństwie do innych baz danych SQL Server usługa Synapse SQL umożliwia użycie tabeli tymczasowej poza procedurą, która ją utworzyła. Tabele tymczasowe utworzone za pośrednictwem dedykowanej puli SQL mogą być używane w dowolnym miejscu w sesji. W związku z tym będziesz mieć bardziej modułowy i możliwy do zarządzania kod, jak pokazano w poniższym przykładzie:

EXEC [dbo].[prc_sqldw_update_stats] @update_type = 1, @sample_pct = NULL;

DECLARE @i INT              = 1
,       @t INT              = (SELECT COUNT(*) FROM #stats_ddl)
,       @s NVARCHAR(4000)   = N''

WHILE @i <= @t
BEGIN
    SET @s=(SELECT update_stats_ddl FROM #stats_ddl WHERE seq_nmbr = @i);

    PRINT @s
    EXEC sp_executesql @s
    SET @i+=1;
END

DROP TABLE #stats_ddl;

Ograniczenia tabeli tymczasowej

Dedykowana pula SQL ma kilka ograniczeń implementacji dla tabel tymczasowych:

  • Obsługiwane są tylko tabele tymczasowe o zakresie sesji. Globalne tabele tymczasowe nie są obsługiwane.
  • Nie można tworzyć widoków w tabelach tymczasowych.
  • Tabele tymczasowe można tworzyć tylko przy użyciu dystrybucji skrótu lub działania okrężnego. Replikowana tymczasowa dystrybucja tabel nie jest obsługiwana.

Tabele tymczasowe w bezserwerowej puli SQL

Tabele tymczasowe w bezserwerowej puli SQL są obsługiwane, ale ich użycie jest ograniczone. Nie można ich używać w zapytaniach skierowanych do plików.

Na przykład nie można dołączyć tabeli tymczasowej z danymi z plików w magazynie. Liczba tabel tymczasowych jest ograniczona do 100, a ich całkowity rozmiar jest ograniczony do 100 MB.

Następne kroki

Aby dowiedzieć się więcej na temat tworzenia tabel, zobacz artykuł Projektowanie tabel przy użyciu zasobów usługi Synapse SQL .