web-dev-qa-db-fra.com

Comment interroger ce 20 millions d'enregistrements plus rapidement?

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 ..
14
balu

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?

9
gbn

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.

6
ggponti

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 ).

6
AndrewSQL

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?

4
Matt M

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.

0
crosenblum