2010-02-18 2 views
4

Dans SQL Server 2005, j'ai une recherche de produit qui ressemble à:SQL SELECT ... WHERE avec REMPLACER - inquiet qu'il est inefficace

select ProductID, Name, Email 
from Product 
where Name = @Name 

On m'a demandé d'ignorer un couple « caractères spéciaux » dans Product.Name, de sorte qu'une recherche de "Pommes de terre" renvoie "Po-ta-toes" ainsi que "Pommes de terre". Ma première pensée est de faire ceci:

select ProductID, Name, Email 
from Product 
where REPLACE(Name, '-', '') = @Name 

... mais à la réflexion, je me demande si je tue les performances en exécutant une fonction sur chaque résultat candidat. Est-ce que SQL a une magie d'optimisation qui l'aide à faire ce genre de chose rapidement? Pouvez-vous penser à quelque chose de plus facile que je pourrais être en mesure d'essayer avec les exigences que j'ai?

+0

Vous pourriez avoir à mordre la balle. Ignorer certains caractères dans une recherche de produit ajoute une tonne de complexité. Dans l'attente de tous les bons moyens autour de cela !! – Craig

+0

pouvez-vous faire une chaîne remplacer dans le code avant de le passer à la procédure stockée? –

Répondre

5

Plus basées sur des normes: Vous pouvez ajouter une nouvelle colonne, par exemple, searchable_name, précalculer les résultats de l'REPLACE (et tout autre tweaks, par exemple, SOUNDEX) sur INSERT/UPDATE et les stocker dans la nouvelle colonne, puis effectuez une recherche contre cette colonne.

Moins basé sur des normes: Beaucoup de SGBDR fournissent une fonctionnalité où vous pouvez créer un INDEX en utilisant une fonction; ceci est souvent appelé un index fonctionnel. Votre situation semble assez bien adaptée à une telle fonctionnalité. Plus puissant/flexible: Utilisez un outil de recherche dédié tel que Lucene. Cela peut sembler excessif pour cette situation, mais ils ont été conçus pour la recherche, et la plupart offrent des algorithmes sophistiqués qui pourraient presque certainement résoudre ce problème.

+0

Je pensais que la nouvelle colonne serait trop lourde, mais cela résoudrait tellement de problèmes. Merci. – dnord

5

Vous obtiendrez probablement de meilleures performances si vous êtes prêt à forcer le premier caractère à alphabétique, comme ça ...

select ProductID, Name, Email 
from Product 
where REPLACE(Name, '-', '') = @Name 
     And Name Like Left(@Name, 1) + '%' 

Si la colonne nom est indexé, vous obtiendrez probablement un indice cherchent à la place d'un scan. L'inconvénient est, vous ne retournerez pas les lignes où la valeur est "-po-ta-to-es" parce que le premier caractère ne correspond pas.

+0

+1 Cela pourrait aider beaucoup et dans les cas où je suis tombé dessus, le premier personnage n'a jamais été spécial. –

+0

Bien que je ne puisse pas en faire ma réponse "acceptée", l'approche est fantastiquement intelligente et je la mets dans mon sac de trucs. Merci. – dnord

0

Pouvez-vous ajouter un champ à votre tableau de produits avec une version de recherche du nom de produit avec des caractères spéciaux déjà supprimés? Ensuite, vous pouvez faire le 'remplacer' une seule fois pour chaque enregistrement, et faire des recherches efficaces contre le nouveau champ.