J'ai une requête SQL qui utilise à la fois des clauses et l'index de texte complet contient des clauses. La requête est construite dynamiquement à partir du code et comprend un nombre variable de l'endroit et contient des clauses. p>
Pour que la requête soit rapide, il est très important que l'indice de texte complet soit recherché avant que le reste des critères ne soit appliqué. P>
Toutefois, SQL Server choisit de traiter les clauses où les clauses contiennent des clauses contenant et que les analyses des tables et la requête est très lente. p>
Je suis capable de réécrire cela en utilisant deux questions et une table temporaire. Quand je le fais, la requête exécute 10 fois plus vite. Mais je ne veux pas faire cela dans le code qui crée la requête parce qu'il est trop complexe. P>
Y a-t-il un moyen de forcer SQL Server à traiter la conception avant toute autre chose? Je ne peux pas forcer un plan (plan d'utilisation) car la requête est construite de manière dynamique et varie beaucoup. p>
Remarque: j'ai le même problème sur SQL Server 2005 et SQL Server 2008. P>
3 Réponses :
Essayez de le faire avec 2 requêtes sans tables Temps:
SELECT * FROM table WHERE id IN ( SELECT id FROM table WHERE contains_criterias ) AND further_where_classes
Vous pouvez signaler votre intention de l'optimiseur comme celle-ci Cependant, SQL est déclarative: vous dites ce que em> vous voulez, pas em> pour le faire. Donc, l'optimiseur peut décider d'ignorer l'imbrication ci-dessus. P> Vous pouvez forcer la table dérivée avec contient pour être matérialisée avant que la clause classique où est appliquée. Je ne garantirai pas la performance. P> SELECT
*
FROM
(
SELECT TOP 2000000000
*
FROM
....
WHERE
CONTAINS
ORDER BY
SomeID
) T1
WHERE
(normal conditions)
Hmm, Nice, j'allais suggérer une boucle Inscrivez-vous si les résultats contenant sont toujours connus pour être petit en nombre, mais c'est beaucoup plus propre, meilleur des deux mondes.
@gbn: Si vous utilisez un CTE, cela ne signifie pas que Force B> Évaluation en premier?
@Yuck: Considérons une macro CTE une macro comme ma table dérivée. C'est-à-dire que j'aurais pu utiliser un CTE à la place. Même résultat ...
@GBN: intéressant. J'étais sous le - erroné apparemment - impression qu'un CTE ressemblait davantage à une table tempentielle implicite qu'une sous-requête.
@Yuck: Cela peut être quand récursif, mais pour ce scénario, c'est une macro de rendre votre code meilleur :-)
@TAO, pouvez-vous s'il vous plaît poster votre solution de convivialité de votre boucle. Bien que moins propre, il pourrait être plus facile de mettre dans notre constructeur de requêtes. Merci
Je confirme que le truc sur top code> fonctionne même si utilisé dans
où code>. Comme
où dans (Select Top ....) code> N'a même pas besoin de faire la sous-requête
Comme je l'ai noté ci-dessus, il ne s'agit pas aussi propre de "matérialiser" la table dérivée que la clause supérieure que @gbn proposait, mais une ligne de jointure de boucle oblige l'ordre d'évaluation et a travaillé pour moi dans le passé. (certes généralement avec deux tables différentes impliquées). Il y a quelques problèmes que:
Voici cependant, étant donné que vous avez demandé: p>
Merci d'avoir pris le temps de poster la réponse.
Ce bit sonne problématique - "La requête est construite de manière dynamique et varie de manière dynamique et varie" - car cela peut signifier que le traitement
contient d'abord code> après peut ne pas être optimal, donc Même si vous réussissez à attacher les mains de l'optimiseur, il peut ne pas avoir les effets désirés.
@Damien_the_unbeliever: La seule solution parfaite serait une solution dans l'optimiseur SQL Server lui-même. Je ne sais pas pourquoi il ne comprend pas que le traitement de la contient est d'abord beaucoup plus rapide. Donc, toute autre solution ne sera pas optimale dans tous les cas. Cependant, je sais que dans notre traitement, le traitement de la contient sera d'abord plus rapide la plupart du temps. Mais vous avez raison; Je ne peux pas le garantir.