Question

I ai une requête avec environ 6-7 tables jointes et un FREETEXT () prédicat de 6 colonnes de la table de base dans le cas.

Maintenant, cette requête a bien fonctionné (en moins de 2 secondes) pour l'année dernière et pratiquement resté inchangé (j'ai essayé les anciennes versions et les problèmes) persiste

Donc, aujourd'hui, tout d'un coup, la même requête prend environ 1-1,5 minutes.

Après avoir vérifié le plan d'exécution dans SQL Server 2005, la reconstruction de l'indice FULLTEXT de ce tableau, la réorganisation de l'index FULLTEXT, création de l'index à partir de zéro, de redémarrer le service SQL Server, le redémarrage de l'ensemble du serveur, je ne sais pas quoi d'autre essayez.

Je mis temporairement la requête à l'utilisation LIKE à la place jusqu'à ce que je comprendre cela (ce qui prend environ 6 secondes maintenant).

Quand je regarde la requête dans l'analyseur de performances des requêtes, quand je compare la'FREETEXT'query avec la requête'LIKE', l'ancien a 350 fois plus de lectures (4.921.261 par rapport à 13943) et 20 fois (38937 vs . 1938) l'utilisation du processeur de celui-ci.

Il est donc vraiment le'FREETEXT'predicate qui l'amène à être si lent.

Quelqu'un at-il des idées sur ce que la raison peut-être? Ou d'autres tests que je pouvais faire?

[Modifier]

Eh bien, je viens à nouveau la requête a couru pour obtenir le plan d'exécution et maintenant il prend 2-5 secondes à nouveau, sans modifications apportées, bien que le problème existait encore hier. Et il n'a pas été en raison de des facteurs externes, comme je l'avais arrêté toutes les applications accédant à la base de données quand je Testée d'abord la question jeudi dernier, il était donc pas due à d'autres charges.

Eh bien, je vais inclure encore le plan d'exécution, mais il pourrait ne pas aider beaucoup maintenant que tout fonctionne à nouveau ... Et méfiez-vous, il est une grande requête à une base de données existante que je ne peux pas changer (c.-à-Normaliser données ou de se débarrasser de quelques tables intermédiaires unneccessary)

plan de requête

ok est complet ici requête

Je pourrait avoir à expliquer ce qu'il fait exactement. Fondamentalement, il obtient des résultats de recherche pour les annonces d'emploi, où il y a deux types d'annonces, les premium et normaux. les résultats sont paginés à 25 résultats par page, 10 ceux de haut et d'affaires en hausse de 15 normaux après cela, s'il y a assez.

donc il y a les deux requêtes internes sélectionner autant de ceux de primes / normales au besoin (par exemple, à la page 10, il va chercher les 100 plus les haut de gamme et les 150 normaux), alors ces deux requêtes sont intercalées avec une commande row_number () et un peu de mathématiques. alors la combinaison est ordonnée par rownumber et la requête est renvoyée. Eh bien, il est utilisé à un autre endroit pour obtenir juste les 25 annonces nécessaires à la page en cours.

Oh, et cette requête est complètement fabriqué dans un fichier Coldfusion héritage énorme et comme il fonctionnait très bien, je n'ai pas osé thouching / changer une grande partie à ce jour ... jamais toucher un système en cours d'exécution et ainsi de suite) Juste petit des choses comme changer des morceaux de la centrale où la clause.

Le fichier génère également d'autres requêtes qui font essentiellement la même chose, mais sans la prime / distinction non premium et beaucoup d'autres variantes de cette requête, donc je ne suis jamais tout à fait sûr comment un changement à l'un d'entre eux pourrait changer la autres ...

Ok que le problème n'a pas fait surface à nouveau, je donne Martin la générosité comme il a été jusqu'à présent le plus utile et je ne voulais pas la prime d'expirer inutilement. Merci à tout le monde pour leurs efforts, je vais essayer vos suggestions si cela se produit à nouveau:)

Était-ce utile?

La solution

Cette question pourrait se poser en raison d'une mauvaise estimation cardinalité du nombre de résultats qui seront retournés par la requête en texte intégral conduisant à une mauvaise stratégie pour la REJOIGNEZ opérations.

Comment trouvez-vous les performances si vous divisez en 2 étapes?

Une nouvelle étape qui alimente une table temporaire ou variable table avec les résultats de la requête de texte intégral et la deuxième modification de votre requête existante pour faire référence à la table temporaire à la place.

(NB: Vous pouvez essayer cette jointure avec et sans OPTION(RECOMPILE) tout en regardant des plans de requête pour (A) un terme de recherche de texte libre qui renvoie de nombreux résultats (B) Un que les rendements seulement une poignée de résultats.)

Modifier Il est difficile de préciser exactement en l'absence de la requête incriminée, mais ce que je veux dire est au lieu de faire

SELECT <col-list>
FROM --Some 6 table Join
WHERE FREETEXT(...);

Comment cela effectuer?

DECLARE @Table TABLE
(
<pk-col-list>
)
INSERT INTO @Table
SELECT PK
FROM YourTable
WHERE FREETEXT(...)

SELECT <col-list>
FROM --Some 6 table Join including onto @Table
OPTION(RECOMPILE)

Autres conseils

En général, quand nous avons cette question, il est à cause de la fragmentation des tables et des statistiques périmées sur les indices en question.

La prochaine fois, essayez de EXEC sp_updatestats après une reconstruction / réindexation.

Voir Utilisation des statistiques pour améliorer les performances des requêtes pour plus d'informations.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top