J'ai un PROC stocké qui recherche des produits (250 000 lignes) à l'aide d'un index de texte complet.
Le processus stocké prend un paramètre qui est la condition de recherche de texte complète. Ce paramètre peut être null, alors j'ai ajouté une vérification nulle et la requête a soudainement commencé à exécuter des ordres de grandeur plus lentement. P> Voici les plans d'exécution: p> Quertise n ° 1
p> requête n ° 2
p> Je dois admettre que je ne suis pas très familier avec les plans d'exécution. La seule différence évidente pour moi est que les jointures sont différentes. J'essaierais d'ajouter un indice mais de ne pas rejoindre dans ma requête, je ne sais pas comment faire ça. P> Je ne comprends pas non plus pourquoi l'indice appelé ix_sectiondid est utilisé, car il s'agit d'un indice que contient la sectionIDE de la colonne et cette colonne n'est utilisée nulle part. p> p>
3 Réponses :
ou code> peut écraser les performances, alors faites-le ainsi:
DECLARE @Filter VARCHAR(100)
SET @Filter = 'FORMSOF(INFLECTIONAL, robe)'
IF @Filter IS NOT NULL
BEGIN
SELECT TOP 100 ID FROM dbo.Products
WHERE CONTAINS(Name, @Filter)
END
ELSE
BEGIN
SELECT TOP 100 ID FROM dbo.Products
END
Nice article - Ajout d'une option (recompilation) code> résout réellement le problème de performance sur la 2e requête (toutefois un autre problème est que
contient () code> augmente une erreur lorsque le paramètre est null, mais C'est un autre problème).
Vous avez introduit un ou des conditions. Dans la plupart des cas, il est tout simplement beaucoup plus rapide de vérifier explicitement pour NULL et de réaliser une requête vs votre méthode.
Par exemple, essayez ceci: p>
Le premier plan de requête semble simple:
contient (nom, @filter) code> li>
- Un scan d'index pour rechercher les autres colonnes des lignes correspondantes li>
- Combinez les deux à l'aide d'une jointure de hachage li>
ol>
le Opérateur de concaténation forme une union de deux matches. Il semble donc que la deuxième requête fait: p>
- Un scan d'index (ultérieurement utilisé pour rechercher d'autres colonnes) li>
- une analyse constante. Je suppose que cela traite votre requête comme non paramétré, le plan de requête n'a donc pas à fonctionner pour une autre valeur de
@filter code>. Si correct, la balayage constante résout @filter n'est pas null code>. Li>
- Une recherche de texte complète à résolution
contient (nom, @filter) code> li>
- Unions le résultat de 3 avec l'ensemble vide de 2 li>
- La boucle relie le résultat de 1 et 4 pour rechercher les autres colonnes li>
ol>
Un jointure de hachage Mémoire à la vitesse de la vitesse; Si votre système a suffisamment de mémoire, c'est beaucoup plus rapide qu'une jointure en boucle. Cela peut facilement expliquer un ralentissement 10-100x. P>
Un correctif consiste à utiliser deux requêtes distinctes: p> xxx pré> p>
Intéressant - Y a-t-il un moyen de forcer une hachage rejoindre la deuxième requête?
Oui, vous pouvez le réécrire en utilisant Inner Hash Join Join Code>, mais ce serait plutôt complexe. Il serait préférable d'utiliser l'une des solutions de l'article de Sommarskog.