Aracılığıyla paylaş


Ayrılmış SQL havuzundaki istatistiklerin doğruluğunu denetleme

Şunlar için geçerlidir: Azure Synapse Analytics

Güncelleştirilmiş istatistikler, en uygun yürütme planını oluşturma açısından kritik önem taşır. İstatistik doğruluğunu saptamayla ilgili olarak değerlendirmeniz gereken iki farklı perspektif vardır:

1\. Adım: Denetim düğümü satır sayısının doğruluğunu onaylama

Ayrılmış SQL havuzunda, dağıtılmış sorgu planları oluşturmaya yönelik birincil altyapının işlem düğümlerindeki satır sayısı hakkında güncelleştirilmiş tutulması gerekir. Satır sayıları arasında tutarsızlık olan tabloları belirlemek için aşağıdaki sorguyu çalıştırın:

SELECT objIdsWithStats.[object_id]
    ,actualRowCounts.[schema]
    ,actualRowCounts.logical_table_name
    ,statsRowCounts.stats_row_count
    ,actualRowCounts.actual_row_count
    ,row_count_difference = CASE 
        WHEN actualRowCounts.actual_row_count >= statsRowCounts.stats_row_count
            THEN actualRowCounts.actual_row_count - statsRowCounts.stats_row_count
        ELSE statsRowCounts.stats_row_count - actualRowCounts.actual_row_count
        END
    ,percent_deviation_from_actual = CASE 
        WHEN actualRowCounts.actual_row_count = 0
            THEN statsRowCounts.stats_row_count
        WHEN statsRowCounts.stats_row_count = 0
            THEN actualRowCounts.actual_row_count
        WHEN actualRowCounts.actual_row_count >= statsRowCounts.stats_row_count
            THEN CONVERT(NUMERIC(18, 0), CONVERT(NUMERIC(18, 2), (actualRowCounts.actual_row_count - statsRowCounts.stats_row_count)) / CONVERT(NUMERIC(18, 2), actualRowCounts.actual_row_count) * 100)
        ELSE CONVERT(NUMERIC(18, 0), CONVERT(NUMERIC(18, 2), (statsRowCounts.stats_row_count - actualRowCounts.actual_row_count)) / CONVERT(NUMERIC(18, 2), actualRowCounts.actual_row_count) * 100)
        END
    ,'UPDATE STATISTICS ' + quotename(actualRowCounts.[schema]) + '.' + quotename(actualRowCounts.logical_table_name) + ';' as update_stats_stmt
FROM (
    SELECT DISTINCT object_id
    FROM sys.stats
    WHERE stats_id > 1
    ) objIdsWithStats
LEFT JOIN (
    SELECT object_id
        ,sum(rows) AS stats_row_count
    FROM sys.partitions
    GROUP BY object_id
    ) statsRowCounts ON objIdsWithStats.object_id = statsRowCounts.object_id
LEFT JOIN (
    SELECT sm.name [schema]
        ,tb.name logical_table_name
        ,tb.object_id object_id
        ,SUM(rg.row_count) actual_row_count
    FROM sys.schemas sm
    INNER JOIN sys.tables tb ON sm.schema_id = tb.schema_id
    INNER JOIN sys.pdw_table_mappings mp ON tb.object_id = mp.object_id
    INNER JOIN sys.pdw_nodes_tables nt ON nt.name = mp.physical_name
    INNER JOIN sys.dm_pdw_nodes_db_partition_stats rg ON rg.object_id = nt.object_id
        AND rg.pdw_node_id = nt.pdw_node_id
        AND rg.distribution_id = nt.distribution_id
    INNER JOIN sys.indexes ind on tb.object_id = ind.object_id
    WHERE rg.index_id < 2 -- In case this condition removed the number of rows will gets duplicated based on the number of index.
    AND ind.type_desc IN ('CLUSTERED COLUMNSTORE', 'HEAP') -- Switch between the CCI (Column store) and HEAP, You should at least keep one value or else the total number of rows will gets duplicated based on the number of indexes.
    GROUP BY sm.name
        ,tb.name
        ,tb.object_id
    ) actualRowCounts ON objIdsWithStats.object_id = actualRowCounts.object_id

2. Adım: İstatistiklerin güncel olduğundan emin olma

Verilerin güncelleştirilmesi, etkili yürütme planları oluşturmak için kullanılan istatistik histogramlarını önemli ölçüde etkileyebilir. İstatistiklerinizin son güncelleştirme tarihinin tablodaki değişiklik desenleriyle uyumlu olup olmadığını belirlemek için aşağıdaki sorguyu çalıştırın:

SELECT ob.[object_id],max(sm.[name]) AS [schema_name]
    ,max(tb.[name]) AS [table_name]
    ,st.[stats_id]
    ,max(st.[name]) AS [stats_name]
    ,string_agg(co.[name], ',') AS [stats_column_names]
    ,STATS_DATE(ob.[object_id], st.[stats_id]) AS [stats_last_updated_date]
    ,'UPDATE STATISTICS ' + quotename(max(sm.[name])) + '.' + quotename(max(tb.[name])) + ';' as [update_stats_stmt]
FROM sys.objects ob
JOIN sys.stats st ON ob.[object_id] = st.[object_id]
JOIN sys.stats_columns sc ON st.[stats_id] = sc.[stats_id]
    AND st.[object_id] = sc.[object_id]
JOIN sys.columns co ON sc.[column_id] = co.[column_id]
    AND sc.[object_id] = co.[object_id]
JOIN sys.types ty ON co.[user_type_id] = ty.[user_type_id]
JOIN sys.tables tb ON co.[object_id] = tb.[object_id]
JOIN sys.schemas sm ON tb.[schema_id] = sm.[schema_id]
WHERE st.[stats_id] > 1
GROUP BY ob.[object_id], st.[stats_id]
ORDER BY stats_last_updated_date

3\. Adım: Belirlenen tablolarda istatistikleri güncelleştirme

Önceki adımlarda aday tabloları tanımladıktan sonra, istatistikleri güncelleştirmek için sorguların sütununda oluşturulan update_stats_stmt deyimleri çalıştırın.

Not

Kullanıcı tarafından oluşturulduğunda bile tek tek istatistikleri güncelleştirmenizi önermeyiz. İstatistik adı belirtilmeden UPDATE STATISTICS komutu çalıştırıldığında hem tabloyla ilişkilendirilmiş tüm istatistikler hem de denetim düğümü satır sayısı güncelleştirilir. Büyük tablolar için uygun doğruluğu elde etmek için veya WITH SAMPLE <SamplePercent> PERCENT kullanarak WITH FULLSCAN varsayılan tarama yüzdesini geçersiz kılmayı düşünebilirsiniz. Söz diziminin tamamı için bkz. UPDATE STATISTICS (Transact-SQL).

Örneğin:

UPDATE STATISTICS [dbo].[MyAwesomeTable];

İstatistikleri güncelleştirdikten sonra istatistik güncelleştirmelerinin yürütme süresini geliştirip geliştirmediğini saptamak için sorunlu sorguyu yeniden çalıştırın.

İstatistik bakımı için daha fazla kaynak