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 ..
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.
źródło
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 ).
źródło
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ć?
źródło
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.
źródło