Czy widok jest szybszy niż proste zapytanie?

359

Jest

select *  from myView

szybciej niż samo zapytanie, aby utworzyć widok (w celu uzyskania tego samego zestawu wyników):

select * from ([query to create same resultSet as myView])

?

Nie jest dla mnie całkowicie jasne, czy widok używa jakiegoś buforowania, dzięki czemu jest szybszy w porównaniu z prostym zapytaniem.

JohnIdol
źródło
7
Nie jestem pewien co do jednego widoku, ale widoki zagnieżdżone to piekło o całkowitej wydajności.
Muflix,

Odpowiedzi:

680

Tak , do widoków można przypisać indeks klastrowy, a kiedy to zrobią, będą przechowywać tymczasowe wyniki, które mogą przyspieszyć wynikowe zapytania.

Aktualizacja: co najmniej trzy osoby zagłosowały za mną w tej sprawie. Z całym szacunkiem uważam, że są po prostu w błędzie; Własna dokumentacja Microsoft wyraźnie pokazuje, że Widoki mogą poprawić wydajność.

Po pierwsze, proste widoki są rozbudowywane i nie przyczyniają się bezpośrednio do poprawy wydajności - to prawda. Jednak indeksowane widoki mogą znacznie poprawić wydajność.

Pozwól mi przejść bezpośrednio do dokumentacji:

Po utworzeniu unikatowego indeksu klastrowego w widoku zestaw wyników widoku jest natychmiast materializowany i zapisywany w pamięci fizycznej w bazie danych, co pozwala zaoszczędzić na kosztach związanych z wykonaniem tej kosztownej operacji w czasie wykonywania.

Po drugie, te indeksowane widoki mogą działać, nawet jeśli nie są bezpośrednio przywoływane przez inne zapytanie, ponieważ optymalizator użyje ich zamiast odwołania do tabeli, gdy jest to właściwe.

Ponownie dokumentacja:

Zindeksowany widok można wykorzystać do wykonania zapytania na dwa sposoby. Kwerenda może bezpośrednio odwoływać się do widoku indeksowanego lub, co ważniejsze, optymalizator kwerendy może wybrać widok, jeśli ustali, że widok może zostać zastąpiony częścią lub całością zapytania w planie najtańszych zapytań. W drugim przypadku zamiast tabel bazowych i ich zwykłych indeksów używany jest widok indeksowany. Do widoku nie trzeba odwoływać się w zapytaniu, aby optymalizator zapytań mógł z niego korzystać podczas wykonywania zapytania. Umożliwia to istniejącym aplikacjom korzystanie z nowo utworzonych widoków indeksowanych bez zmiany tych aplikacji.

Ta dokumentacja, a także wykresy przedstawiające poprawę wydajności, można znaleźć tutaj .

Aktualizacja 2: odpowiedź została skrytykowana na podstawie tego, że to „indeks” zapewnia przewagę wydajności, a nie „widok”. Łatwo to jednak obalić.

Powiedzmy, że jesteśmy firmą programistyczną w małym kraju; Jako przykład wykorzystam Litwę. Sprzedajemy oprogramowanie na całym świecie i przechowujemy nasze dane w bazie danych SQL Server. Odnosimy sukcesy, więc za kilka lat mamy ponad 1 000 000 rekordów. Jednak często musimy zgłaszać sprzedaż do celów podatkowych i okazało się, że sprzedaliśmy tylko 100 kopii naszego oprogramowania w naszym kraju. Tworząc indeksowany widok tylko litewskich rekordów, możemy zachować potrzebne rekordy w indeksowanej pamięci podręcznej, jak opisano w dokumentacji MS. Kiedy uruchomimy nasze raporty dotyczące sprzedaży na Litwie w 2008 r., Nasze zapytanie przeszuka indeks o głębokości zaledwie 7 (Log2 (100) z nieużywanymi liśćmi). Gdybyśmy zrobili to samo bez WIDOKU i polegając tylko na indeksie w tabeli, musielibyśmy przejść przez drzewo indeksów o głębokości wyszukiwania 21!

Oczywiście sam widok zapewniłby nam przewagę wydajności (3x) nad prostym użyciem samego indeksu. Próbowałem użyć rzeczywistego przykładu, ale zauważysz, że prosta lista sprzedaży na Litwie dałaby nam jeszcze większą przewagę.

Zauważ, że po prostu używam prostej b-drzewa dla mojego przykładu. Chociaż jestem całkiem pewien, że SQL Server używa jakiegoś wariantu b-drzewa, nie znam szczegółów. Niemniej jednak chodzi o to.

Aktualizacja 3: Pojawiło się pytanie, czy widok indeksowany korzysta tylko z indeksu umieszczonego na podstawowej tabeli. Innymi słowy, parafrazując: „widok indeksowany jest tylko odpowiednikiem standardowego indeksu i nie oferuje niczego nowego ani unikalnego dla widoku”. Gdyby to była prawda, powyższa analiza byłaby nieprawidłowa! Pozwól, że przedstawię cytat z dokumentacji Microsoft, który pokazuje, dlaczego uważam, że ta krytyka jest nieprawidłowa lub prawdziwa:

Używanie indeksów w celu poprawy wydajności zapytań nie jest nową koncepcją; jednak widoki indeksowane zapewniają dodatkowe korzyści w zakresie wydajności, których nie można osiągnąć przy użyciu standardowych indeksów.

W połączeniu z powyższym cytatem dotyczącym trwałości danych w pamięci fizycznej i innymi informacjami w dokumentacji dotyczącej tworzenia indeksów w widokach, myślę, że można bezpiecznie powiedzieć, że widok indeksowany to nie tylko buforowany wybór SQL, który korzysta z indeks zdefiniowany w głównej tabeli. Dlatego nadal podtrzymuję tę odpowiedź.

Mark Brittingham
źródło
29
Tak, indeksowane widoki mogą znacznie poprawić wydajność. Ale indeksowane widoki to nie tylko „widoki” i ogólnie mówiąc, normalny „widok” nie jest szybszy niż powiązane z nimi zapytania.
BradC
10
@Charles - nie ma znaczenia, czy to indeks, fakt, że widok może wykorzystać indeks, a surowe zapytanie nie wystarczy
annakata 13.01.2009
196
/ brawo @Mark za to, że stał na swoim miejscu i racjonalnie argumentował to
annakata,
17
Och, stary, mam 8 głosów negatywnych na ten temat! Dziwi mnie, że ludzie tak szybko głosowali, nie mając przynajmniej odwagi Charlesa, by argumentować.
Mark Brittingham
8
Ponieważ tabela może mieć tylko jeden indeks klastrowy i MOŻNA utworzyć osobny indeks klastrowy w widoku (ponieważ pola w indeksie klastrowym są niezależnie zachowywane na stronach indeksu), jest to oszustwo (po pracy?) pozwala uzyskać DWIE indeksy klastrowe na jednym stole.
Charles Bretana,
51

Ogólnie rzecz biorąc, nie. Widoki są używane przede wszystkim ze względu na wygodę i bezpieczeństwo i same w sobie nie przynoszą korzyści w zakresie prędkości.

To powiedziawszy, SQL Server 2000 i wyżej mają funkcję o nazwie Widoki indeksowane, która może znacznie poprawić wydajność, z kilkoma zastrzeżeniami:

  1. Nie każdy widok można przekształcić w widok indeksowany; muszą przestrzegać ustalonych szczegółowych wytycznych , które (między innymi ograniczeniami) oznacza, że nie może obejmować wspólne elementy, takie jak kwerendy COUNT, MIN, MAX, lub TOP.
  2. Widoki indeksowane wykorzystują fizyczną przestrzeń w bazie danych, podobnie jak indeksy w tabeli.

W tym artykule opisano dodatkowe korzyści i ograniczenia indeksowanych widoków :

Możesz…

  • Definicja widoku może odwoływać się do jednej lub więcej tabel w tej samej bazie danych.
  • Po utworzeniu unikalnego indeksu klastrowego można utworzyć dodatkowe indeksy nieklastrowane względem widoku.
  • Możesz aktualizować dane w bazowych tabelach - w tym wstawki, aktualizacje, usuwa, a nawet obcina.

Nie możesz…

  • Definicja widoku nie może odwoływać się do innych widoków lub tabel w innych bazach danych.
  • Nie może zawierać COUNT, MIN, MAX, TOP, złączeń zewnętrznych ani kilku innych słów kluczowych lub elementów.
  • Nie możesz modyfikować bazowych tabel i kolumn. Widok jest tworzony za pomocą opcji Z SCHEMABINDOWANIEM.
  • Nie zawsze można przewidzieć, co zrobi optymalizator zapytań. Jeśli korzystasz z wersji Enterprise, automatycznie uwzględni unikalny indeks klastrowy jako opcję zapytania - ale jeśli znajdzie „lepszy” indeks, zostanie on użyty. Możesz zmusić optymalizator do użycia indeksu za pomocą podpowiedzi WITH NOEXPAND - ale zachowaj ostrożność, używając dowolnej podpowiedzi.
BradC
źródło
3
całkowicie się nie zgadzam ... czytanie z widoku pozwala na przepisanie kodu SQL .. i ogólnie SZYBCIEJ jest czytać z widoku (niż ze zrzutu widoku).
Aaron Kempf
@AaronKempf, chciałbym zobaczyć odniesienia do tego, to nie było moje doświadczenie. Kiedy szukam „zobacz przepisany SQL”, wszystkie wyniki, które otrzymuję, odnoszą się do Oracle, a nie do serwera SQL, np. Docs.oracle.com/cd/E14072_01/server.112/e10810/qrbasic.htm
BradC
Wczoraj po prostu przeprowadzałem testy porównawcze. Byłem oszołomiony. Zasadniczo, jeśli zrobię zrzut z widoku (do tabeli), każde uruchamiane przeze mnie zapytanie jest WOLNIEJSZE, ponieważ większość zapytań przechodzi przez widok jak masło i zostaje przepisana przez optymalizator zapytań. Przynajmniej tak zakładam. Postaram się wkrótce napisać na nim wpis na blogu, testy porównawcze były dość fascynujące. Zasadniczo widoki wspaniale wpływają na wydajność.
Aaron Kempf,
@AaronKempf Nie jestem pewien, czy to nawet ten sam scenariusz, co oryginalne pytanie (dotyczy zapytania zamiast umieszczenia tego samego zapytania w widoku). W każdym razie nie widzę, w jaki sposób zmaterializowanie widoku w tabeli spowolniłoby (to właśnie robi widok indeksowany), chyba że twoja nowa tabela nie ma dobrych indeksów.
BradC,
1
Ćwiek; Napisałem naprawdę zły post na blogu o tym, jak widoki oszczędzają mi 99% moich wyników w tej sytuacji. Planuję napisać kilka innych artykułów, ale wiem, że muszę w tym dodać TON więcej szczegółów. Czy masz coś przeciwko temu, aby spojrzeć na to i powiedzieć mi, co myślisz o moim opisie? Wiem, że to nie będzie miało większego sensu (dopóki nie skończę 2-3 innych artykułów) .. ale jestem szalenie zakochany w widokach i byłem od dłuższego czasu! accessadp.com/2013/01/22/do-views-increase-performance
Aaron Kempf
14

Przynajmniej w SQL Server plany kwerend są przechowywane w pamięci podręcznej planu zarówno dla widoków, jak i zwykłych zapytań SQL, w oparciu o parametry zapytania / widoku. Oba są usuwane z pamięci podręcznej, gdy nie są używane przez wystarczająco długi okres, a miejsce jest potrzebne na inne nowo przesłane zapytanie. Następnie, jeśli zostanie wydane to samo zapytanie, zostanie ono ponownie skompilowane, a plan zostanie ponownie umieszczony w pamięci podręcznej. Więc nie, nie ma różnicy, biorąc pod uwagę, że ponownie używasz tego samego zapytania SQL i tego samego widoku z tą samą częstotliwością.

Oczywiście, ogólnie widok, z samej swojej natury (że ktoś myślał, że należy go używać wystarczająco często, aby zrobić z niego widok), jest na ogół bardziej prawdopodobne, że zostanie „ponownie użyty” niż jakakolwiek dowolna instrukcja SQL.

Charles Bretana
źródło
14

EDYCJA: Myliłem się i powinieneś zobaczyć odpowiedź Marka powyżej.

Nie mogę mówić z doświadczenia z SQL Server , ale dla większości baz danych odpowiedź brzmiałaby „nie”. Jedyną potencjalną korzyścią wynikającą z korzystania z widoku jest to, że potencjalnie może on tworzyć ścieżki dostępu na podstawie zapytania. Ale głównym powodem korzystania z widoku jest uproszczenie zapytania lub ustandaryzowanie sposobu uzyskiwania dostępu do niektórych danych w tabeli. Ogólnie rzecz biorąc, nie uzyskasz korzyści w zakresie wydajności. Jednak mogę się mylić.

Wymyślę nieco bardziej skomplikowany przykład i sam go zobaczę.

Ryan Guill
źródło
1
innym powodem poglądów jest pomoc w kontroli dostępu w modelach opartych na
rolach
1
Mylisz się co do poprawy wydajności. Nie wyjaśniłem wystarczająco, aby przekonać niektóre osoby w moim oryginalnym komentarzu, ale MS ma wyraźną dokumentację, w jaki sposób korzystać z widoków w celu poprawy wydajności. Zobacz moją (obecnie mocno ocenioną) odpowiedź poniżej.
Mark Brittingham
7

Może to być szybsze, jeśli utworzysz widok zmaterializowany ( z powiązaniem schematu ). Nie zmaterializowane widoki są wykonywane tak jak zwykłe zapytania.

Otávio Décio
źródło
Schematyzacja ma niewiele wspólnego z wydajnością, wiąże schemat widoku z tabelą bazową, dzięki czemu pozostaje zsynchronizowany i stanowi wstępne wymaganie dla widoków indeksowanych.
Sam Saffron,
5

Rozumiem, że jakiś czas temu widok byłby szybszy, ponieważ SQL Server mógłby przechowywać plan wykonania, a następnie użyć go zamiast próbować go opracowywać w locie. Myślę, że dzisiejszy wzrost wydajności prawdopodobnie nie jest tak świetny, jak kiedyś, ale musiałbym zgadywać, że można by nieznacznie poprawić wykorzystanie tego widoku.

EJ Brennan
źródło
Takie było moje zrozumienie: kiedyś miało znaczenie, już nie ma
annakata
Nie działa z punktu widzenia wydajności - działa jako środek ograniczenia dostępu. Ale to byłby inny temat. ;)
AnonJr
och,
jasne
4

Zdecydowanie widok jest lepszy niż zapytanie zagnieżdżone dla programu SQL Server. Nie wiedząc dokładnie, dlaczego jest to lepsze (dopóki nie przeczytam postu Marka Brittinghama), przeprowadziłem kilka testów i doświadczyłem prawie szokującej poprawy wydajności podczas korzystania z widoku w porównaniu do zagnieżdżonego zapytania. Po uruchomieniu każdej wersji zapytania kilkaset razy z rzędu wersja podglądu zapytania zakończyła się w połowie czasu. Powiedziałbym, że to dla mnie wystarczający dowód.


źródło
Dzięki Jordan ... cieszę się, że cała ta teoria sprawdza się w prawdziwym świecie.
Mark Brittingham
Mam doświadczenie z widokiem zagnieżdżonym (widok w widoku) i była bardzo zła wydajność. Kiedy wszystkie widoki zostały przepisane na podselekcje, wydajność była wielokrotnie szybsza, więc może jest miejsce na poważne testy.
Muflix,
2

Spodziewałbym się, że dwa zapytania będą działać identycznie. Widok jest niczym więcej niż zapisaną definicją zapytania, nie ma buforowania ani przechowywania danych dla widoku. Optymalizator skutecznie zamieni twoje pierwsze zapytanie w drugie, gdy je uruchomisz.

Tony Andrews
źródło
Jeśli widok jest niewielkim zestawem pól, a te pola są następnie pokryte indeksem, czy SQL Server jest wystarczająco sprytny, aby użyć tego indeksu pokrywającego podczas wypełniania drugiej formy zapytania?
AnthonyWJones
1

Wszystko zależy od sytuacji. Widoki indeksowane MS SQL są szybsze niż normalny widok lub zapytanie, ale widoków indeksowanych nie można używać w odbiciu lustrzanej bazy danych (MS SQL).

Widok w dowolnej pętli spowoduje poważne spowolnienie, ponieważ widok jest ponownie zapełniany za każdym razem, gdy jest wywoływany w pętli. Taki sam jak zapytanie. W tej sytuacji tymczasowa tabela używająca # lub @ do przechowywania danych w pętli jest szybsza niż widok lub zapytanie.

Wszystko zależy więc od sytuacji.

Dasboot
źródło
0

Nie ma praktycznej różnicy, a jeśli przeczytasz BOL, przekonasz się, że zawsze stary zwykły SQL SELECT * FROM X korzysta z buforowania planu itp.

keithwarren7
źródło
0

Przechowywanie planu wykonania powinno być trywialne, ale będzie nieistotne.

JosephStyons
źródło
0

Celem widoku jest ciągłe używanie zapytania. W tym celu SQL Server, Oracle itp. Zazwyczaj zapewniają „widok buforowany” lub „skompilowany” widok, poprawiając w ten sposób jego wydajność. Zasadniczo powinno to działać lepiej niż „proste” zapytanie, chociaż jeśli zapytanie jest naprawdę bardzo proste, korzyści mogą być znikome.

Teraz, jeśli wykonujesz złożone zapytanie, utwórz widok.


źródło
0

Według mnie korzystanie z widoku jest nieco szybsze niż normalne zapytanie. Moja procedura składowana trwała około 25 minut (praca z innymi większymi zestawami rekordów i wieloma połączeniami), a po użyciu widoku (bez klastrów) wydajność była tylko trochę szybsza, ale wcale nie znacząca. Musiałem użyć innych technik / metod optymalizacji zapytań, aby dokonać radykalnej zmiany.

kta
źródło
To, jak piszemy / projektujemy zapytanie, jest bardzo ważne.
kta
Znalazłem użycie CTE do ograniczenia danych zwracanych z tabeli, a następnie wykonywania całej pracy / łączenia itp. Poza CTE znacznie poprawiło wydajność w wielu przypadkach
MattE
0

Wybór z widoku lub z tabeli nie będzie miał większego sensu.

Oczywiście, jeśli widok nie zawiera niepotrzebnych połączeń, pól itp. Możesz sprawdzić plan wykonania swoich zapytań, połączeń i indeksów używanych do poprawy wydajności widoku.

Możesz nawet utworzyć indeks widoków, aby przyspieszyć wyszukiwanie. http://technet.microsoft.com/en-us/library/cc917715.aspx

Ale jeśli szukasz czegoś w stylu „% ...%”, silnik SQL nie skorzysta z indeksu w kolumnie tekstowej. Jeśli możesz zmusić użytkowników do wyszukiwania takich jak „...%”, to będzie to szybkie

odniósł się do odpowiedzi na forach asp: https://forums.asp.net/t/1697933.aspx?Which+is+faster+when+using+SELECT+query+VIEW+or+Table+

Mohamad Reza Shahrestani
źródło
0

Wbrew wszelkim oczekiwaniom widoki są w niektórych okolicznościach znacznie wolniejsze.

Odkryłem to niedawno, gdy miałem problemy z danymi pobranymi z Oracle, które wymagały masowania w innym formacie. Może 20k wierszy źródłowych. Mały stolik. Aby to zrobić, zaimportowaliśmy dane Oracle w sposób niezmieniony do tabeli, a następnie wykorzystaliśmy widoki do wyodrębnienia danych. Na podstawie tych poglądów mieliśmy poglądy wtórne. Może 3-4 poziomy widoków.

Jedno z ostatnich zapytań, które wyodrębniło może 200 wierszy, potrwa ponad 45 minut! To zapytanie było oparte na kaskadzie widoków. Może 3-4 poziomy głębokości.

Mogłem wziąć każdy z omawianych widoków, wstawić jego kod SQL do jednego zagnieżdżonego zapytania i wykonać go w ciągu kilku sekund.

Odkryliśmy nawet, że możemy nawet zapisać każdy widok do tabeli tymczasowej i zapytać go zamiast widoku, a to wciąż jest o wiele szybsze niż zwykłe użycie widoków zagnieżdżonych.

Jeszcze dziwniejsze było to, że wydajność była dobra, dopóki nie osiągnęliśmy limitu wierszy źródłowych pobieranych do bazy danych, po prostu spadła z klifu w ciągu kilku dni - wystarczyło kilka kolejnych wierszy źródłowych.

Tak więc używanie zapytań pobranych z widoków pobranych z widoków jest znacznie wolniejsze niż zapytanie zagnieżdżone - co nie ma dla mnie sensu.

Ian
źródło
-1

Natknąłem się na ten wątek i chciałem po prostu udostępnić ten post od Brenta Ozara jako coś do rozważenia podczas korzystania z grup dostępności.

Raport o błędzie Brenta Ozara

JohnH
źródło