Comment effectuer une recherche en texte intégral sur plusieurs critères sur des tables jointes à gauche dans SQL Server ?

StackOverflow https://stackoverflow.com/questions/35954

  •  09-06-2019
  •  | 
  •  

Question

J'ai une requête qui ressemble à ceci à l'origine :

select c.Id, c.Name, c.CountryCode, c.CustomerNumber, cacc.AccountNumber, ca.Line1, ca.CityName, ca.PostalCode
from dbo.Customer as c
left join dbo.CustomerAddress as ca on ca.CustomerId = c.Id
left join dbo.CustomerAccount as cacc on cacc.CustomerId = c.Id
where  c.CountryCode = 'XX' and (cacc.AccountNumber like '%C17%' or c.Name like '%op%'       
or ca.Line1 like '%ae%' or ca.CityName like '%ab%' or ca.PostalCode like '%10%')

Sur une base de données contenant 90 000 enregistrements, cette requête prend environ 7 secondes à s'exécuter (évidemment, toutes les jointures et toutes les mentions J'aime sont éprouvantes).

J'ai essayé de trouver un moyen de réduire le temps d'exécution des requêtes grâce à une recherche en texte intégral sur les colonnes concernées.Cependant, je n'ai pas vu d'exemple de recherche en texte intégral comportant trois jointures de table comme celle-ci, d'autant plus que ma condition de jointure ne fait pas partie du terme de recherche.

Existe-t-il un moyen de le faire dans la recherche en texte intégral ?


@David

Oui, il y a des index sur les identifiants.

J'ai essayé d'ajouter des index sur les éléments CustomerAddress (CityName, PostalCode, etc.) et cela a réduit la requête à 3 secondes, mais je trouve toujours cela trop lent pour quelque chose comme ça.

Notez que tous les champs de texte (à l'exception des identifiants) sont des nvarchars et que Line1 est un nvarchar 1000, cela peut donc affecter la vitesse, mais quand même.

Était-ce utile?

La solution

Exécutez-le via l'analyseur de requêtes et voyez quel est le plan de requête.Je suppose que la racine double (c.-à-d.Les recherches %ae%) l'obligent à effectuer une analyse de table lors de la recherche des lignes correspondantes.Les recherches à double racine sont intrinsèquement lentes, car vous ne pouvez généralement utiliser aucun type d'index pour les faire correspondre.

Autres conseils

NOTE:Ce n'est pas vraiment une réponse, juste une tentative de clarifier ce qui pourrait réellement être à l'origine du ou des problèmes de performances.

90 000 enregistrements représentent en réalité un ensemble de données assez petit et la requête est relativement simple avec seulement deux jointures.Avez-vous des index sur CustomerAddress.CustomerId et CustomerAccount.CustomerId ?Cela semble plus susceptible de causer des problèmes de performances que les prédicats de la condition Where LIKE.Cherchez-vous généralement une correspondance sur toutes ces colonnes en même temps ?

Je ferais écho à la suggestion de David.Vous souhaiterez probablement examiner comment le SGBDR exécute votre requête (par exemple, via des analyses de tables ou à l'aide d'index).

Une vérification rapide consisterait à chronométrer uniquement la partie de la requête impliquant la recherche de texte.Quelque chose comme ça:

SELECT  ca.Line1, ca.CityName, ca.PostalCode
FROM    CustomerAddress as ca
WHERE   ca.CustomerId = <some id number>
AND     (ca.Line1 LIKE '%ae%' OR ca.CityName LIKE '%ab%' OR ca.PostalCode LIKE '%10%');

Si cela prend beaucoup de temps, alors le LIKEC'est le problème (supprimez une expression à la fois du ORed pour voir si une seule de ces colonnes est à l'origine du ralentissement).Si c'est rapide, alors les jointures sont suspectes.

Vous pouvez également écrire une requête similaire pour la table CustomerAccount.

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