Para uma funcionalidade de pesquisa, estou usando uma exibição que possui os registros de todas as tabelas nas quais preciso pesquisar. A vista possui quase 20 milhões de registros. As pesquisas nessa visualização estão demorando muito.
Onde devo procurar melhorar o desempenho dessa visão?
A definição aproximada para a visualização está abaixo. Inclui treze mesas e cerca de trinta campos.
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 ..
fonte
Sem mais detalhes sobre a visualização e as tabelas, a resposta é "depende", mas você pode começar a examinar a cláusula WHERE da visualização para os campos que podem exigir índices.
fonte
Além do que os outros disseram (cláusula WHERE, INDEXes que podem ajudar), sugiro que você queira considerar visualizações indexadas - supondo que seja possível criar índices na visualização ( detalhes ). Você também poderá aplicar a dica NOEXPAND em suas consultas ( detalhes ).
fonte
A resposta genérica é dar uma olhada no plano de execução. Suas junções são indexadas? Seus campos de saída estão incluídos nesses índices? Você está apenas produzindo as colunas que precisa ver?
fonte
O que eu provavelmente faria é apenas criar 2 visualizações
A primeira visualização é apenas dos campos que preciso pesquisar; apenas esses campos. Eu retornaria o campo de ID para cada linha, mais que tipo de tabela sua pesquisa. Fiz uma coisa semelhante ao criar uma visualização UNION ALL que pesquisou várias tabelas. Apenas certifique-se de incluir o ID, o tipo e os campos de texto que eu queria pesquisar.
A 2ª exibição trataria da exibição dos resultados reunidos na 1ª exibição e teria todas as tabelas necessárias para exibir resultados, ou talvez, em vez de uma exibição, o tornasse um procedimento armazenado.
Eu faria um UNION ALL, com um GROUP BY na parte inferior, e não faria todos aqueles JOINTERS EXTERIORES ESQUERDOS.
fonte