Requête SQL n'utilisant pas l'index requirejs dans SQL Server

J'ai deux index non groupés sur la table A:

  • detected_utc index

colonne de key: DETECTED_UTC ASC

Colonnes incluses: APPROVAL_STATUS , IS_ROOT , AGENTGUID

  • index agentguid

Colonne key: agentguid

Maintenant la requête utilise l'index d' agentguid et prend 1min 17 sec.

Mais si je spécifie un indice de requête comme

 option (table hint(A, index(DETECTED_UTC))) 

Cela prend 4 sec.

Pourquoi SQL Server ne considère pas detected_utc dans le plan de requête. La requête peut-elle être modifiée pour utiliser l'index detected_utc? Je ne souhaite pas spécifier d'indicateur de requête dans ma requête.

 SELECT AUTO_ID FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY A.DETECTED_UTC DESC ) AS ROWNUM , A.AUTO_ID , A.DETECTED_UTC FROM A INNER JOIN B ON A.AGENTGUID = B.AgentGUID LEFT JOIN C ON B.ParentID = C.AutoID WHERE ( DETECTED_UTC > DATEADD(day, -7, GETUTCDATE()) ) AND ( APPROVAL_STATUS = '0' ) AND IS_ROOT = '1' AND EXISTS ( SELECT 1 FROM B epf WHERE epf.AgentGUID IS NOT NULL AND epf.AgentGUID = A.AGENTGUID AND epf.ParentID IN ( SELECT AutoID FROM C WHERE AutoID IN ( SELECT NodeID FROM D WHERE D.GroupID IN ( 42 ) ) ) ) ) AS TEMP WHERE ROWNUM >= 1000 AND ROWNUM < 1041 ORDER BY DETECTED_UTC DESC 

  • Votre AGENTGUID est sur AGENTGUID
  • Votre WHERE utilise DETECTED_UTC, APPROVAL_STATUS, IS_ROOT

Seule la colonne DETECTED_UTC est utile dans l'index detected_utc de l'optimiseur: les autres colonnes utilisées sont des colonnes incluses. Votre indice indice remplace ceci: Je suppose que vous verrez des searchs ou des spools ou des sortings dans le plan avec l'indice de contourner les colonnes incluses n'étant pas des colonnes keys dans l'index

Je m'attendrais à ce que l'un d'eux serait plus utile

 (AGENTGUID, DETECTED_UTC DESC, APPROVAL_STATUS, IS_ROOT) INCLUDE (AUTO_ID) (DETECTED_UTC DESC, AGENTGUID, APPROVAL_STATUS, IS_ROOT) INCLUDE (AUTO_ID) 

L'optimiseur estime que JOIN est la partie la plus sélective de la requête. Basé sur cette estimation, il fait des choix pour rendre cette jointure aussi performante que possible.

Votre utilisation d'un indice indique que la sélectivité estimée est erronée. La mise à jour des statistics et la recompilation du code PEUVENT aider ici, mais tout aussi peu probable: La requête est très complexe et le meilleur plan de requête (et donc quel index utiliser) dépendra des données existantes et des caractéristiques de ces données , dans plusieurs tables différentes.

Je continuerais soit à utiliser l'indice (si les caractéristiques de base de vos données ne changeraient pas), soit à créer un index composé comme suggéré par GBN.