Comment puis-je forcer une requête à ne pas utiliser d'index sur une table donnée?

Je fais actuellement des tests pour déterminer les implications de performance de l'inclusion d'un index sur une colonne donnée dans SQL Server 2005.

L'ensemble de données de test que j'utilise contient environ ~ 72 millions de lignes (environ 6 Go de données). Afin de réellement tester la performance de l'index, je dois être capable de comparer les performances avec et sans l'index.

C'est très bien, mais créer un index n'est pas une opération bon marché. Si je veux pour tester la table sans l'index, je dois, à tout le moins, désactiver l'index. Pour tester avec l'index, je dois le réactiver, ce qui prend beaucoup de temps.

Est-il possible de forcer SQL Server 2005 à ignorer un index donné lorsqu'il exécute une requête? Je ne veux pas avoir à désactiver l'index juste pour tester une requête car il faut si longtemps pour désactiver l'index.

30
demandé sur Mike Bailey 2012-06-13 18:23:13

3 réponses

SELECT *
FROM MyTable WITH (INDEX(0))
WHERE MyIndexedColumn = 0

Query utiliserait normalement l'index sur MyIndexedColumn, mais en raison de l'indice de table, il sera à la place tablescan.


SELECT *
FROM MyTable WITH (INDEX(IndexName))
WHERE MyIndexedColumn = 0

La requête utiliserait normalement L'index sur MyIndexedColumn, mais en raison de l'indice de table, elle utilisera à la place L'index nommé IndexName.

44
répondu Amy B 2012-06-13 14:29:58

Je travaille avec tous les différents types de DB et je ne me souviens jamais de l'indice spécifique quand j'en ai besoin. Par conséquent, j'utilise une approche SQL pure qui (actuellement) fonctionne avec toutes les bases de données qui traversent mon chemin.

L'idée est juste de rendre impossible pour la base de données d'utiliser l'index spécifique en obscurcissant l'expression respective dans le SQL. Par exemple

SELECT *
  FROM MyTable
 WHERE MyIndexedColumn + 0 = 0

De Même, vous pouvez ajouter une chaîne vide à une valeur de chaîne. Les optimiseurs actuels ne résolvent pas de telles expressions ne peuvent pas utiliser un index sur (MyIndexedColumn).

C'est en fait un anti-modèle que j'ai décrit dans mon livre. Voici quelques sur la page à propos de mathématiques dans SQL

C'est définitivement assez bon pour des tests ad hoc. Dans le code de production, les indices sont bien sûr plus expressifs!

7
répondu Markus Winand 2013-09-17 05:22:42

Vous pouvez désactiver l'index que vous ne voulez pas utiliser dans la même transaction que vous exécutez le code de test, assurez-vous simplement de restaurer la transaction à la fin. Cela garantit que le code de test n'utilisera pas l'index mais empêche l'index d'être désactivé.

BEGIN TRANSACTION

    ALTER INDEX [MyIndex] ON MyTable DISABLE;

    EXEC TestCode;

ROLLBACK

Cela fonctionne mieux si vous avez un cas complexe où votre code de test utilise un certain nombre d'indices à des moments différents et que vous voulez tester si l'ajout d'un nouveau permettrait d'améliorer les choses.

-3
répondu zlangner 2013-09-16 18:06:26