Pour une fonctionnalité de recherche, j'utilise une vue contenant les enregistrements de toutes les tables dans lesquels j'ai besoin de rechercher. La vue comporte près de 20 millions d'enregistrements. Les recherches contre cette vue prennent trop de temps.
Où devrais-je chercher à améliorer la performance de cette vue?
La définition approximative de la vue est ci-dessous. Il comprend treize tables et une trentaine de champs.
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 ..
Une vue est la macro qui se développe. Donc, si votre vue est une jointure de 2 tables, le plan d'exécution montrera les 2 tables. La vue est transparente.
Cela ne s'applique pas si la vue est indexée/matérialisée. Cependant, alors vous ne poseriez pas cette question.
Alors, que dit le plan d'exécution? La DTA? Index manquant DMV Query? Query DMV la plus cher?
Sans plus de détails sur la vue et les tables La réponse est "Cela dépend", mais vous pouvez commencer à examiner la clause de votre vue pour les champs pouvant nécessiter des index.
En plus de ce que d'autres d'autres ont dit (où la clause, les index qui pourraient aider) je suggère que vous souhaitiez peut-être envisager des vues indexées - en supposant que cela soit même possible de créer des index sur la vue ( détails ). Ensuite, vous pourrez également appliquer l'indice NOEXPAND dans vos questions ( détails ).
La réponse générique est de jeter un coup d'œil au plan d'exécution. Vos jointures sont-elles indexées? Vos champs de sortie sont-ils inclus dans ces index? Ne sortez-vous que les colonnes que vous devez voir?
Ce que je ferais probablement, c'est juste créer 2 vues
La 1ère vue est juste des champs dont j'ai besoin pour rechercher; Juste ces champs. Je retournerais le champ ID pour chaque ligne, ainsi que quel type de table votre recherche. J'ai fait une chose similaire en créant un syndicat tout affichage qui recherchait plusieurs tables. Je viens de m'assurer d'inclure l'ID, le type et les champs de texte, je voulais rechercher.
La 2e vue gérerait l'affichage des résultats recueillis à la 1ère vue et aurait chaque table que vous devez afficher des résultats, ou peut-être au lieu d'une vue, en faire une procédure stockée.
Je ferais un syndicat tous, avec un groupe en bas, et je ne ferais pas toutes ces jointures extérieures gauche.