web-dev-qa-db-fra.com

Comment rechercher des lignes contenant une sous-chaîne?

Si je stocke un TEXTAREA HTML dans ma base de données ODBC chaque fois que l'utilisateur soumet un formulaire, quelle est l'instruction SELECT pour récupérer 1) toutes les lignes qui contiennent une sous-chaîne donnée 2 ) toutes les lignes qui ne le font pas (et la recherche est-elle sensible à la casse?)


Modifier: si LIKE "%SUBSTRING%" va être lent, serait-il préférable de tout récupérer et de le trier en PHP?

35
Mawg

Eh bien, vous pouvez toujours essayer WHERE textcolumn LIKE "%SUBSTRING%" - mais cela est garanti d'être assez lent, car votre requête ne peut pas faire de correspondance d'index car vous recherchez des caractères sur le côté gauche.

Cela dépend du type de champ - une zone de texte n'est généralement pas enregistrée comme VARCHAR, mais plutôt comme (une sorte de) champ TEXT, vous pouvez donc utiliser l'opérateur MATCH AGAINST .

Pour obtenir les colonnes qui ne correspondent pas, placez simplement un NOT devant le même: WHERE textcolumn NOT LIKE "%SUBSTRING%".

Que la recherche respecte ou non la casse dépend de la façon dont vous stockez les données, en particulier de la COLLATION que vous utilisez. Par défaut, la recherche ne respecte pas la casse.

Réponse mise à jour pour refléter la mise à jour de la question:

Je dis que faire un WHERE field LIKE "%value%" est plus lent que WHERE field LIKE "value%" si le champ de la colonne a un index, mais c'est encore beaucoup plus rapide que d'obtenir toutes les valeurs et d'avoir votre filtre d'application. Les deux scénarios:

1/Si vous le faites SELECT field FROM table WHERE field LIKE "%value%", MySQL analysera la table entière et n'enverra que les champs contenant "value".

2/Si vous faites SELECT field FROM table et que votre application (dans votre cas PHP) ne filtre que les lignes contenant "valeur", MySQL analysera également la table entière, mais enverra tous les champs à PHP, qui devra alors faire un travail supplémentaire. C'est beaucoup plus lent que le cas n ° 1.

Solution: veuillez utiliser la clause WHERE et utiliser EXPLAIN pour voir les performances.

37
Konerak

Infos sur la recherche plein texte de MySQL. Ceci est limité aux tables MyISAM, donc peut ne pas convenir si vous souhaitez utiliser un type de table différent.

http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

Même si WHERE textcolumn LIKE "%SUBSTRING%" va être lent, je pense qu'il vaut probablement mieux laisser la base de données s'en occuper plutôt que d'avoir PHP s'en occuper. S'il est possible de restreindre les recherches par d'autres critères (plage de dates , utilisateur, etc.), vous pouvez trouver que la recherche de sous-chaîne est OK (ish).

Si vous recherchez des mots entiers, vous pouvez extraire tous les mots individuels dans un tableau séparé et l'utiliser pour restreindre la recherche de sous-chaîne. (Ainsi, lorsque vous recherchez "ma chaîne de recherche", vous recherchez la recherche de mot la plus longue uniquement pour la recherche de sous-chaîne sur les enregistrements contenant le mot "recherche")

5
Jaydee