Jak szybciej sprawdzić ten widok rekordów 20 milionów?

14

Do funkcji wyszukiwania używam widoku, który zawiera rekordy ze wszystkich tabel, w których muszę wyszukiwać. Widok ma prawie 20 milionów rekordów. Wyszukiwanie w tym widoku zajmuje zbyt dużo czasu.

Gdzie powinienem szukać poprawy wydajności tego widoku?

Wstępna definicja widoku znajduje się poniżej. Zawiera trzynaście stołów i około trzydziestu pól.

CREATE VIEW [dbo].[v_AllForSearch]
AS
SELECT 
  FT.firstField AS [firstField]
, FT.fld_primary AS [fld_primary]
, FT.fld_thirdField AS [thirdField]
, FT.fld_fourthField AS [fourthField]           
, ISNULL(ST.[fld_firstSearchField],'') AS [firstSearchField]
, ISNULL(TT.[fld_thirdSearch],'') AS thirdSearch
, ISNULL(TT.[fld_fourthSearch],'')AS fourthSearch
, ISNULL(TT.[fld_fifthSearch],'')AS fifthSearch
, ISNULL(FRT.[fld_sixthSearch],'') As [sixthSearch]
, ISNULL(FRT.[fld_seventhSearch],'') AS [seventhSearch]
, ISNULL(FRT.[fld_eightSearch],'')AS [eightSearch]
, ISNULL(FIT.[fld_nineSearch],'') AS [nineSearch]
, ISNULL(SIT.[fld_tenthSearch],'')AS [tenthSearch]
, ISNULL(SET.[fld_eleventhSearch],'') AS [eleventhSearch]
, ISNULL(ET.[twelthSearch],'')AS [twelthSearch]
, ISNULL(NT.[thirteenthSearch],'')AS [thirteenthSearch]
, ISNULL(NT.[fourteenSearch],'') AS [fourteenSearch]
, ISNULL(NT.[fifteenSearch],'') AS [fifteenSearch]
, ISNULL(NT.[sxteenSearch],'')  AS [sxteenSearch]
, ISNULL(NT.[seventeenSearch],'') AS [seventeenSearch]
, ISNULL(NT.[eighteenSearch],'')AS [eighteenSearch]
, ISNULL(TT.[ninteenSearch],'') AS [ninteenSearch]
, ISNULL(ELT.[twentySearch],'') AS [twentySearch]
, ISNULL(ELT.[twentyOneSearch],'') AS [twentyOneSearch]
, ISNULL(TWT.[twentyTwoSearch],'') AS [twentyTwoSearch]
, ISNULL(THT.twentyThree,'') AS [twentyThree]
, ISNULL(THT.twentyFour,'') AS [twentyFour]
, ISNULL(THT.twentyFive,'') AS [twentyFive]
, ISNULL(THT.twentySix,'') AS [twentySix]
FROM 
      tblFirstTable AS FT         
      LEFT JOIN [tblSecondTable] AS ST 
            ON ST.[fld_primary] = FT.[fld_primary]        
      LEFT JOIN [tblThirdTable] AS TT 
            ON TT.[fld_primary] = FT.[fld_primary]        
      LEFT JOIN [tblFourthTable] AS FRT 
            ON FRT.[fld_primary] = FT.[fld_primary]       
      LEFT JOIN [tblFifthTable] AS FIT 
            ON FIT.[fld_primary] = FT.[fld_primary]       
      LEFT JOIN [tblSixthTable] AS SIT 
            ON SIT.[fld_primary] = FT.[fld_primary]       
      LEFT JOIN [tblSeventhTable] AS SET 
            ON SET.[fld_primary] = FT.[fld_primary]       
      LEFT JOIN [tblEighthTable] AS ET 
            ON ET.[fld_primary] = FT.[fld_primary] 
      LEFT JOIN [tblNinthTable] AS NT 
            ON NT.[fld_primary] = FT.[fld_primary]        
      LEFT JOIN [tblELTnthTable] AS TT 
            ON TT.[fld_primary] = FT.[fld_primary]        
      LEFT JOIN [tblEleventhTable] AS ELT 
            ON ELT.[fld_primary] = FT.[fld_primary]       
      LEFT JOIN [tblTwelthTable] AS TWT 
                            ON TWT.[fld_id] = ELT.[fld_id]  
              LEFT JOIN [tblThirteenthTable] AS THT
            ON THT.[firstField]= FT.[firstField]
WHERE fld_Status ..
balu
źródło

Odpowiedzi:

9

Widok to makro, które się rozwija. Więc jeśli twój widok to JOIN 2 tabel, plan wykonania pokaże 2 tabele. Widok jest przejrzysty.

Nie ma to zastosowania, jeśli widok jest indeksowany / zmaterializowany. Jednak nie zadałbyś tego pytania.

Co mówi plan wykonania? DTA? Brakuje zapytania o indeksy DMV? Najdroższe zapytanie DMV?

gbn
źródło
Może zadaje pytanie o zmaterializowany widok i nie zdaje sobie sprawy, że zazwyczaj jest on implementowany jako kolejna tabela, więc można go indeksować itp.
Joe
@Joe: być może, ale OP nie poprosiłoby o pomoc, gdyby znali różnice ...
gbn
Pytanie jest oznaczone dla MS SQL Server, więc zamiast „widoków zmaterializowanych” powinniśmy mówić o „widokach indeksowanych”;)
AndrewSQL,
1
@AndrewSQL: Tak. Ale powinniśmy zadbać o niższe formy życia ...
gbn
6

Bez dalszych szczegółów na temat widoku i tabel odpowiedź brzmi „to zależy”, ale możesz zacząć patrzeć na klauzulę WHERE twojego widoku dla pól, które mogą wymagać indeksów.

ggponti
źródło
1
Ale miałem wrażenie, że generalnie widoki nie korzystają w znacznym stopniu z indeksów (... zgodnie z „Powiedziano mi, że ten facet znam”)
jcolebrand
5
@jcolebrand: indeksy są ogólnie bardzo pomocne w widokach, w zależności od ich wykorzystania. Zasadniczo, gdy zostaną użyte w danym zapytaniu, skorzystają, jakby ich kod został wstawiony bezpośrednio do zapytania. W przypadku prostych widoków + zapytań oznacza to, że używają indeksów, podobnie jak każde proste zapytanie. W przypadku bardziej złożonych widoków / zapytań zależy od tego, jak dobrze planista zapytań może zmienić kolejność i zoptymalizować pracę do wykonania. Najlepszym sposobem, aby to zobaczyć, jest wybranie dużego zestawu danych i wykonanie przy użyciu nich przykładowych widoków i zapytań oraz sprawdzenie, co wyświetla plan zapytań SSMS, co robi z nimi QP.
David Spillett,
6

Oprócz tego, co powiedzieli inni (klauzula WHERE, INDEKSY, które mogą pomóc) Sugeruję, aby rozważyć indeksowane widoki - zakładając, że można nawet tworzyć indeksy w widoku ( szczegóły ). Wtedy możesz również zastosować wskazówkę NOEXPAND do swoich zapytań ( szczegóły ).

AndrewSQL
źródło
Te szczegóły brzmią obiecująco. Pozwól, że je wypróbuję, a wrócę do wyników.
balu
4

Ogólną odpowiedzią jest spojrzenie na plan wykonania. Czy twoje połączenia są indeksowane? Czy twoje pola wyjściowe są uwzględnione w tych indeksach? Czy wyświetlasz tylko kolumny, które chcesz zobaczyć?

Matt M.
źródło
0

To, co prawdopodobnie bym zrobił, to po prostu utworzyć 2 widoki

  • Pierwszy widok to tylko pola, które muszę wyszukać; tylko te pola. Zwrócę pole identyfikatora dla każdego wiersza oraz rodzaj tabeli, której szukasz. Zrobiłem podobnie, tworząc widok UNION ALL, który przeszukiwał wiele tabel. Po prostu upewniłem się, że podam identyfikator, typ i pola tekstowe, które chciałem wyszukać.

  • Drugi widok poradzi sobie z wyświetlaniem wyników zebranych w pierwszym widoku i sprawi, że każda tabela, której potrzebujesz do wyświetlenia wyników, a może zamiast widoku, sprawi, że będzie to procedura składowana.

Zrobiłbym UNION ALL, z GROUP BY na dole, i nie zrobiłbym wszystkich tych LEFT OUTO JOIN.

Crosenblum
źródło