2009-11-20 3 views
2

J'ai besoin d'extraire des informations d'un champ de texte qui peut contenir l'une des nombreuses valeurs. Le SQL ressemble à:Efficacité de l'instruction SQL 'LIKE' avec un grand nombre de clauses

SELECT fieldname 
FROM table 
WHERE bigtextfield LIKE '%val1%' 
    OR bigtextfield LIKE '%val2%' 
    OR bigtextfield LIKE '%val3%' 
    . 
    . 
    . 
    OR bigtextfield LIKE '%valn%' 

Ma question est: comment cela est efficace lorsque le nombre de valeurs se rapproche des centaines, des milliers et peut-être? Y a-t-il une meilleure manière de faire cela?

Une solution serait de créer une nouvelle table/colonne avec seulement les valeurs que je suis après et procédez comme suit:

SELECT fieldname 
FROM othertable 
WHERE value IN ('val1', 'val2', 'val3', ... 'valn') 

Ce que j'imagine est beaucoup plus efficace car il n'a qu'à faire exactement correspondance de chaîne. Le problème avec ceci est que ce sera beaucoup de travail pour maintenir cette table à jour.

BTW J'utilise MS SQL Server 2005.

+1

Je serais inquiet à propos de la correction, aussi. '% val1%' correspond à 'val11'. –

+0

sql server 2005 offre-t-elle l'indexation de texte intégral? cela ne serait-il pas utile? – andrewWinn

+0

C'est le cas. Ça aide. – intgr

Répondre

5

Cette fonctionnalité est déjà présente dans la plupart des moteurs SQL, y compris MS SQL Server 2005. Il est appelé indexation en texte intégral; voici quelques ressources:

+0

Comment cela aidera-t-il à rechercher avec les caractères génériques principaux? – Quassnoi

+0

Ce n'est pas le cas, mais l'auteur a déjà fourni un "index de texte intégral" rudimentaire comme une solution satisfaisante dans sa question: 'SELECT fieldname FROM othertable WHERE valeur IN ('val1', 'val2', 'val3', ... 'valn') ' – intgr

+0

Quand je viens de le lire, j'ai eu l'impression que' @ op' voulait correspondre à quelque chose comme 'nval12' avec '% val1%'. Mais maintenant je vois que ce n'est probablement pas le cas et ce dont il a besoin, c'est dénormaliser la table. +1, puisque dans ce cas votre réponse est la manière la plus efficace de gérer la structure actuelle. – Quassnoi

1

Cette volonté inévitable nécessitent une analyse complète (sur la table ou sur un indice) avec un filtre.

La condition IN ne sera pas utile ici, car il ne fonctionne pas sur LIKE

Vous pouvez faire quelque chose comme ceci:

SELECT * 
FROM master 
WHERE EXISTS 
     (
     SELECT NULL 
     FROM values 
     WHERE name LIKE '%' + value + '%' 
     ) 

, mais être à peine plus efficace.

Toutes les conditions littérales seront transformées en CONSTANT SCAN, ce qui est similaire à la sélection dans la même table, mais intégrée dans la mémoire.

2

Je ne pense pas que le principal problème est le nombre des valeurs des critères - mais le simple fait qu'une clause WHERE avec bigtextfield LIKE '%val1%' ne peut jamais vraiment être très efficace - même avec juste une seule valeur. Le problème est que si vous avez un espace réservé comme "%" au début de votre terme de recherche, tous les index sont hors de la fenêtre et ne peuvent plus être utilisés.

Ainsi, vous effectuez simplement une recherche dans chaque table de votre tableau en effectuant une analyse de table complète dans le processus. Maintenant, votre performance dépend fondamentalement juste du nombre de lignes dans votre table ....

J'appuie la recommandation de Intgr - si vous avez besoin de le faire souvent, un regard sérieux sur l'indexation du texte intégral.

1

La meilleure solution pour cela est de reconcevoir et de se débarrasser de ce champ qui stocke plusieurs valeurs et en faire une table liée à la place. Cela viole l'une des premières règles de conception de base de données.

Vous ne devriez pas stocker plusieurs valeurs dans un champ et des requêtes lentes comme ceci sont la raison pour laquelle.Si vous ne pouvez pas faire cela alors l'indexation de test complet est votre seul espoir.

+0

Je n'ai pas conçu la base de données, je peux voir à quel point le design actuel est défectueux, je me demandais juste si j'avais d'autre choix que de le refaire! –

Questions connexes