Aracılığıyla paylaş


Synapse SQL'de geçici tablolar

Bu makale, geçici tabloları kullanmaya yönelik temel yönergeleri içerir ve Synapse SQL'de oturum düzeyi geçici tabloların ilkelerini vurgular.

Hem ayrılmış SQL havuzu hem de sunucusuz SQL havuzu kaynakları geçici tabloları kullanabilir. Sunucusuz SQL havuzu, bu makalenin sonunda açıklanan sınırlamalara sahiptir.

Geçici tablolar

Geçici tablolar, özellikle ara sonuçların geçici olduğu dönüştürme sırasında verileri işlerken yararlıdır. Synapse SQL ile oturum düzeyinde geçici tablolar bulunur. Yalnızca oluşturuldukları oturum tarafından görülebilirler. Bu nedenle, bu oturum sona erdiğinde otomatik olarak bırakılırlar.

Ayrılmış SQL havuzundaki geçici tablolar

Ayrılmış SQL havuzu kaynağında, sonuçları uzak depolama yerine yerel olarak yazıldığından geçici tablolar bir performans avantajı sunar.

Geçici tablo oluşturma

Geçici tablolar, tablonuzun adının önüne bir #eklenerek oluşturulur. Örneğin:

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
)

Geçici tablolar da tam olarak aynı yaklaşım kullanılarak CTAS oluşturulabilir:

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]
)
;

Uyarı

CTAS güçlü bir komutdur ve işlem günlüğü alanı kullanımında verimli olmanın ek avantajına sahiptir.

Geçici tabloları bırak

Yeni bir oturum oluşturulduğunda geçici tablo bulunmamalıdır. Ancak, aynı ada sahip bir geçici oluşturan aynı saklı yordamı çağırıyorsanız, deyimlerinizin CREATE TABLE başarılı olduğundan emin olmak için DROP ile basit bir ön varlık denetimi kullanın.

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

Kodlama tutarlılığı için bu deseni hem tablolar hem de geçici tablolar için kullanmak iyi bir uygulamadır. Ayrıca, işiniz bittiğinde geçici tabloları kaldırmak için kullanmak DROP TABLE iyi bir fikirdir.

Saklı yordam geliştirmede, bu nesnelerin temizlendiğinden emin olmak için bir yordamın sonunda bırakma komutlarının topluca kullanılması yaygın bir uygulamadır.

DROP TABLE #stats_ddl

Kodu modüler hale

Geçici tablolar bir kullanıcı oturumunda herhangi bir yerde kullanılabilir. Bu özellik daha sonra uygulama kodunuzu modüler hale getirmek için kullanılabilir. Örnek olarak, aşağıdaki depolanan prosedür, veritabanındaki tüm istatistikleri istatistik adına göre güncellemek için DDL oluşturur.

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

Bu aşamada meydana gelen tek işlem, #stats_ddl geçici tablosunu oluşturan saklı yordamın yaratılmasıdır. Saklı yordam, eğer zaten mevcutsa #stats_ddl'yi düşürür. Bu bırakma işlemi, oturum içinde birden çok kez çalıştırıldığında başarısız olmamasını sağlar.

Saklı yordamın sonunda bir DROP TABLE olmadığından saklı yordam tamamlandığında, oluşturulan tablo kalır ve saklı yordamın dışında okunabilir.

Synapse SQL, diğer SQL Server veritabanlarının aksine, geçici tabloyu oluşturan yordamın dışında kullanmanıza olanak tanır. Ayrılmış SQL havuzu aracılığıyla oluşturulan geçici tablolar, oturumun içinde herhangi bir yerde kullanılabilir. Sonuç olarak, aşağıdaki örnekte gösterildiği gibi daha modüler ve yönetilebilir kodunuz olacaktır:

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;

Geçici tablo sınırlamaları

Ayrılmış SQL havuzunun geçici tablolar için birkaç uygulama sınırlaması vardır:

  • Yalnızca oturum kapsamlı geçici tablolar desteklenir. Genel Geçici Tablolar desteklenmez.
  • Görünümler geçici tablolarda oluşturulamaz.
  • Geçici tablolar yalnızca karma veya dönüşümlü dağıtımla oluşturulabilir. Çoğaltılmış geçici tabloların dağıtımı desteklenmez.

Sunucusuz SQL havuzunda geçici tablolar

Sunucusuz SQL havuzunda geçici tablolar desteklenir ama bunların kullanımı sınırlıdır. Dosyaları hedefleyen sorgularda kullanılamazlar.

Örneğin geçici tabloyu depolamadaki dosyalardan gelen verilerle birleştiremezsiniz. Geçici tablo sayısı 100 ile ve bunların toplam boyutu da 100 MB'la sınırlıdır.

Sonraki adımlar

Tablo geliştirme hakkında daha fazla bilgi edinmek için Synapse SQL kaynaklarını kullanarak tablo tasarlama makalesine bakın.