Zauważyłem stosunkowo długo działającą (20 min +) operację automatycznych aktualizacji statystyk w codziennej kompilacji magazynu danych. Stół dotyczy
CREATE TABLE [dbo].[factWebAnalytics](
[WebAnalyticsId] [bigint] IDENTITY(1,1) NOT NULL,
[MarketKey] [int] NOT NULL CONSTRAINT [DF_factWebAnalytics_MarketKey] DEFAULT ((-1)),
/*Other columns removed*/
CONSTRAINT [PK_factWebAnalytics] PRIMARY KEY CLUSTERED
(
[MarketKey] ASC,
[WebAnalyticsId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [MarketKeyPS]([MarketKey])
) ON [MarketKeyPS]([MarketKey])
Działa to na Microsoft SQL Server 2012 (SP1) - 11.0.3513.0 (X64), więc zapisywalne indeksy magazynu kolumn nie są dostępne.
Tabela zawiera dane dla dwóch różnych kluczy Market. Kompilacja przełącza partycję dla określonego klucza MarketKey na tabelę pomostową, wyłącza indeks magazynu kolumn, wykonuje niezbędne zapisy, odbudowuje magazyn kolumn, a następnie włącza go ponownie.
Plan wykonania statystyk aktualizacji pokazuje, że wyciąga wszystkie wiersze z tabeli, sortuje je, pobiera oszacowaną liczbę wierszy źle i przechodzi do tempdb
poziomu rozlewania 2.
Bieganie
SELECT [s].[name] AS "Statistic",
[sp].*
FROM [sys].[stats] AS [s]
OUTER APPLY sys.dm_db_stats_properties ([s].[object_id], [s].[stats_id]) AS [sp]
WHERE [s].[object_id] = OBJECT_ID(N'[dbo].[factWebAnalytics]');
Przedstawia
Jeśli jawnie staram się zmniejszyć wielkość próby statystyk tego indeksu do tej używanej przez innych z
UPDATE STATISTICS [dbo].[factWebAnalytics] [PK_factWebAnalytics] WITH SAMPLE 897667 ROWS
Kwerenda jest uruchamiana od ponad 20 minut, a plan wykonania pokazuje, że przetwarza wszystkie wiersze, a nie żądaną 897 667 próbkę.
Statystyki generowane na końcu tego wszystkiego nie są bardzo interesujące i zdecydowanie nie wydają się uzasadniać czasu spędzonego na pełnym skanie.
Statistics for INDEX 'PK_factWebAnalytics'.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Name Updated Rows Rows Sampled Steps Density Average Key Length String Index
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PK_factWebAnalytics Jan 22 2016 11:31AM 420072086 420072086 2 0 12 NO 420072086
All Density Average Length Columns
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0.5 4 MarketKey
2.380544E-09 12 MarketKey, WebAnalyticsId
Histogram Steps
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 0 3.441652E+08 0 1
2 0 7.590685E+07 0 1
Jakieś pomysły, dlaczego spotykam się z tym zachowaniem i jakie kroki mogę podjąć oprócz NORECOMPUTE
tych?
Skrypt repro jest tutaj . Po prostu tworzy tabelę z klastrowanym PK i indeksem magazynu kolumn i próbuje zaktualizować statystyki PK o małej wielkości próbki. Nie używa partycjonowania - co pokazuje, że aspekt partycjonowania nie jest wymagany. Jednak użycie partycjonowania opisanego powyżej pogarsza sytuację, ponieważ wyłączenie partycji, a następnie jej ponowne włączenie (nawet bez żadnych innych zmian) zwiększy licznik modyfikacji_dwukrotnie liczbę wierszy w partycji, tym samym gwarantując, że statystyki będą uważane za nieaktualne i automatycznie aktualizowane.
Próbowałem dodać indeks nieklastrowany do tabeli, jak wskazano w KB2986627 (oba przefiltrowane bez wierszy, a następnie, gdy to się nie powiedzie, niefiltrowane NCI również bez efektu).
Repro nie wykazało problematycznego zachowania w kompilacji 11.0.6020.0, a po aktualizacji do SP3 problem został już rozwiązany.
SELECT WebAnalyticsId, MarketKey from [dbo].[factWebAnalytics] TABLESAMPLE (897667 ROWS) ORDER BY MarketKey, WebAnalyticsId
działa dla mnie w mniej niż 30 sekund. Nie używa jednak indeksu magazynu kolumn. Wykorzystuje indeks klastrowany.