Testuję różne architektury dla dużych tabel i jedną z sugestii, które widziałem, jest użycie widoku podzielonego na partycje, w którym duży stół jest podzielony na serię mniejszych „podzielonych na partycje” tabel.
Testując to podejście, odkryłem coś, co nie ma dla mnie większego sensu. Kiedy filtruję „kolumnę partycjonowania” w widoku faktów, optymalizator szuka tylko odpowiednich tabel. Ponadto, jeśli filtruję tę kolumnę w tabeli wymiarów, optymalizator eliminuje niepotrzebne tabele.
Jeśli jednak odfiltruję jakiś inny aspekt wymiaru, optymalizator będzie szukał wartości PK / CI każdej tabeli podstawowej.
Oto pytania, o których mowa:
select
od.[Year],
AvgValue = avg(ObservationValue)
from dbo.v_Observation o
join dbo.ObservationDates od
on o.ObservationDateKey = od.DateKey
where o.ObservationDateKey >= 20000101
and o.ObservationDateKey <= 20051231
group by od.[Year];
select
od.[Year],
AvgValue = avg(ObservationValue)
from dbo.v_Observation o
join dbo.ObservationDates od
on o.ObservationDateKey = od.DateKey
where od.DateKey >= 20000101
and od.DateKey <= 20051231
group by od.[Year];
select
od.[Year],
AvgValue = avg(ObservationValue)
from dbo.v_Observation o
join dbo.ObservationDates od
on o.ObservationDateKey = od.DateKey
where od.[Year] >= 2000 and od.[Year] < 2006
group by od.[Year];
Oto link do sesji SQL Sentry Plan Explorer.
Pracuję nad partycjonowaniem większej tabeli, aby zobaczyć, czy dostanę eliminację partycji, aby zareagować w podobny sposób.
Dostaję eliminację partycji dla (prostego) zapytania, które filtruje aspekt wymiaru.
Tymczasem oto kopia bazy danych przeznaczona wyłącznie do statystyk:
https://gist.github.com/swasheck/9a22bf8a580995d3b2aa
„Stary” estymator liczności otrzymuje tańszy plan, ale wynika to z niższych szacunków liczności przy każdym z (niepotrzebnych) indeksów.
Chciałbym wiedzieć, czy istnieje sposób na to, aby optymalizator użył kolumny klucza podczas filtrowania według innego aspektu wymiaru, aby mógł wyeliminować szukanie w zbędnych tabelach.
Wersja SQL Server:
Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
Feb 20 2014 20:04:26
Copyright (c) Microsoft Corporation
Developer Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
źródło
CREATE STATISTICS [_WA_Sys_00000008_2FCF1A8A] ON [dbo].[Observation_2010]([StationStateCode]) WITH STATS_STREAM = 0x01000000010000000000000000000000D4531EDB00000000D5080000000000009508000000000000AF030000AF000000020000000000000008D000340000000007000000E65DE0007DA5000076F9780000000000867704000000000000000000ABAAAA3C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ObservationDates
tabeli. Nie dostaję tego samego planu co Paul, nawet z 4199, i myślę, że właśnie dlatego.ObservationDates
. Skończyłem biegaćUPDATE STATISTICS ObservationDates WITH ROWCOUNT = 10000
ręcznie, aby uzyskać plan, który zademonstrował Paul.ObservationDates
więc nie jestem pewien, co się z tym dzieje. też nie jestem w stanie uzyskać planu generowanego przez Paula. Spróbuję aktualizacji, aby zobaczyć.Odpowiedzi:
Włącz flagę śledzenia 4199.
Musiałem także wydać:
aby uzyskać plany pokazane poniżej. Brak danych statystycznych dla tej tabeli. Liczba 73 049 pochodzi z informacji o liczności tabeli w załączniku do Eksploratora planu. Użyłem programu SQL Server 2014 SP1 CU4 (kompilacja 12.0.4436) z dwoma procesorami logicznymi, maksymalną pamięcią ustawioną na 2048 MB i bez flag śledzenia oprócz 4199.
Powinieneś otrzymać plan wykonania z dynamiczną eliminacją partycji:
Fragment planu:
Może to wyglądać gorzej, ale wszystkie filtry są filtrami początkowymi . Przykładowy predykat to:
Podczas iteracji pętli testowany jest predykat początkowy i tylko wtedy, gdy zwraca on wartość true, wykonywane jest wyszukiwanie klastrowane indeksu poniżej. Stąd dynamiczna eliminacja partycji.
Być może nie jest to tak skuteczne jak eliminacja statyczna, szczególnie jeśli plan jest równoległy.
Może trzeba spróbować podpowiedzi jak
MAXDOP 1
,FAST 1
lubFORCESEEK
w celu uzyskania tego samego planu. Wybór kalkulatorów kosztów z widokami podzielonymi na partycje (np. Tabele podzielone na partycje) może być trudny.Chodzi o to, że potrzebujesz planu z filtrami początkowymi, aby uzyskać dynamiczną eliminację partycji za pomocą widoków podzielonych na partycje.
Zapytania z osadzonymi
USE PLAN
wskazówkami: (przez gist.github.com):źródło
Moja obserwacja zawsze była taka, że musisz wyraźnie określić wartość (lub zakres wartości) kolumny partycji w zapytaniu, aby uzyskać „eliminację tabeli” w widoku podzielonym na partycje. Jest to oparte na doświadczeniu w używaniu partycjonowanych widoków w produkcji od SQL Server 2000 do SQL Server 2014.
SQL Server nie ma koncepcji operatora łączenia w pętli, w którym silnik może dynamicznie celować wyszukiwanie bezpośrednio do odpowiedniej tabeli po wewnętrznej stronie pętli w oparciu o wartość wiersza po zewnętrznej stronie pętli. Jednak, jak wyjaśnia odpowiedź Paula , istnieje możliwość planu z filtrami początkowymi, aby dynamicznie pomijać nieistotne tabele po wewnętrznej stronie pętli w stałym czasie (w przeciwieństwie do logarytmiki poprzez faktyczne wyszukiwanie).
Należy jednak pamiętać, że w przypadku tabel podzielonych na partycje ten rodzaj wyszukiwania (do określonej partycji) jest obsługiwany.
Jeśli nie chcesz używać widoków podzielonych na partycje, inną opcją jest podzielenie zapytania na wiele zapytań, takich jak:
To daje następujący plan. Istnieje teraz dodatkowe zapytanie dotyczące tabeli wymiarów, ale zapytanie dotyczące (prawdopodobnie znacznie większej) tabeli faktów jest zoptymalizowane.
źródło
20000101
i20051231
zamiast zmiennych (lub wykonaj coś podobnego za pomocą dwóch osobnych zapytań w swojej aplikacji), to tak, ten sam efekt zostałby osiągnięty bez użycia zmiennych.