Pour une fonctionnalité de recherche, j'utilise une vue qui contient les enregistrements de toutes les tables dans lesquelles je dois rechercher. La vue compte près de 20 millions d'enregistrements. Les recherches contre ce point de vue prennent trop de temps.
Où dois-je chercher pour améliorer les performances 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 ..
Sans plus de détails sur la vue et les tables, la réponse est "cela dépend", mais vous pouvez commencer à regarder la clause WHERE de votre vue pour les champs qui peuvent nécessiter des index.
la source
En plus de ce que d'autres ont dit (clause WHERE, INDEX qui pourraient aider), je suggère que vous souhaitiez peut-être envisager des vues indexées - en supposant qu'il est même possible de créer des index sur la vue ( détails ). Ensuite, vous pourrez peut-être également appliquer l'indice NOEXPAND dans vos requêtes ( détails ).
la source
La réponse générique est de jeter un œil au plan d'exécution. Vos jointures sont-elles indexées? Vos champs de sortie sont-ils inclus dans ces index? Produisez-vous uniquement les colonnes que vous devez voir?
la source
Ce que je ferais probablement, c'est juste de créer 2 vues
La 1ère vue n'est que les champs que je dois rechercher; juste ces champs. Je retournerais le champ ID pour chaque ligne, plus le type de table que vous recherchez. J'ai fait une chose similaire en créant une vue UNION ALL qui a recherché 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 rassemblés dans la 1ère vue, et aurait chaque table dont vous avez besoin pour afficher les résultats, ou peut-être au lieu d'une vue, en faire une procédure stockée.
Je ferais un UNION ALL, avec un GROUP BY en bas, et je ne ferais pas tous ces JOINTS GAUCHE EXTÉRIEURS.
la source