Nous avons récemment couru dans le problème de point de basculement et certaines de nos requêtes de rapport qui utilisaient une exécution complète dans quelques secondes prennent désormais plus de 2 minutes car l'optimiseur de requête ignore simplement l'indice non clustered sur le Colonne de recherche. Un exemple de requête ci-dessous:
select top 100 *
from [dbo].[t_Call]
where ID > 0
and throwtime between '3/20/2014 7:00:00 AM' and '3/24/2014 6:59:59 AM'
order by id
La colonne ID
est en clustered Index et Throwtime
a une index non clustered. Dans ce cas, nous avons remarqué que commander par throwtime
au lieu de ID
modifications Le plan de requête et l'indice non clustered est utilisé. Nous envisagons également d'archiver certaines des anciennes données (il a actuellement 20 mln Lignes!!). Mais faire ces changements dans l'application va prendre du temps et je dois trouver un moyen de faire des rapports raisonnablement rapides, sans apporter des changements au niveau de l'application (eh bien, telle est la vie!).
Entrez le Guide du plan. J'ai créé le guide de plan ci-dessous avec un indice de requête d'index non clustered et pour une raison quelconque, l'index non clustered n'est toujours pas utilisé. Est-ce que je manque quelque chose?
EXEC sp_create_plan_guide
@name = N'[prod2reports_callthrowtime]',
@stmt = N'select top 100 *
from [dbo] . [t_Call]
where ID > @0 and @1 < = ThrowTime and ThrowTime < = @2 order by ID',
@type = N'SQL',
@module_or_batch = N'select top 100 *
from [dbo] . [t_Call]
where ID > @0 and @1 < = ThrowTime and ThrowTime < = @2 order by ID',
@params = N'@0 int, @1 datetime, @2 datetime',
@hints = N'OPTION (TABLE HINT( [dbo] . [t_Call],
INDEX(IDX_NC_t_call_ThrowtimeProblemCodes)))'
GO
La requête doit correspondre exactement, y compris les espaces. Je vous suggère d'obtenir la requête du cache et de le créer à partir de cela plutôt que d'y entrer dans une autre manière.
Lisez votre article lié à nouvea
Écrire un guide de plan pour forcer l'utilisation de votre index n'est presque certainement pas ce que vous voulez, car il forcera des recherches inefficaces sur les signets. Selon votre article, la solution correcte pour la performance la plus efficace de cette requête serait de modifier votre index pour être un Index non groupé, dans d'autres Les mots, soit ajouter toutes les colonnes de votre table à l'index, ou (de préférence), ajoutez simplement les colonnes dont vous avez besoin pour cette requête, puis modifiez la sélection pour tirer ces colonnes.