La façon la plus rapide pour trouver chaîne par chaîne en SQL?
J'ai l'immense table avec 2 colonnes: Id et le Titre. L'Id est de type bigint et je suis libre de choisir le type de Titre de colonne: colonne de type varchar, char, texte, que ce soit. Titre de la colonne contient du texte aléatoire des chaînes de caractères comme "abcdefg", "q", "allyourbasebelongtous" avec un maximum de 255 caractères.
Ma tâche est d'obtenir des chaînes par sous-chaîne donnée. Les chaînes ont également aléatoire de longueur et peut être début, au milieu ou à la fin des chaînes. Le moyen le plus évident pour l'exécuter:
SELECT * FROM t LIKE '%abc%'
Je ne se soucient pas de l'INSÉRER, il me suffit de faire vite sélectionne. Que puis-je faire pour effectuer une recherche rapide?
- Je utiliser MS SQL Server 2008 R2, la recherche plein texte sera inutile, autant que je le vois.
- Bienvenue dans le monde merveilleux de très mauvaises performances de la base 🙂
- Pourquoi de recherche de texte intégral être inutile?
- pourrait sous-chaînes de pions? Si vous pouvez séparer les mots par un espace, une virgule ou un tiret, j'ai une idée. Laissez-moi savoir.
- Combien de lignes de la table?
- Chaînes de caractères dans le Titre ne sont pas des phrases et ils n'ont pas de limites de mot. Je me demande si le texte complet de la recherche toujours de l'aide ici.
- Comment le mal est l'interrogation d'une indexé correctement table avec une seule clause LIKE sur une de 255 caractères de la colonne de l'exécution?
- O - Avec un
LIKE '%<anything>%'
requête, il n'y a pas une telle chose comme "indexé correctement'. Aucun indice ne sera jamais utilisable, tout simplement parce que le premier %. - Juste pensé que je voudrais éviter un problème de performance due à une autre requête.
Vous devez vous connecter pour publier un commentaire.
Si vous souhaitez utiliser moins d'espace que Randy de réponse et il y a beaucoup de répétition dans vos données, vous pouvez créer un N-Aire structure d'arbre de données où chaque arête est le caractère suivant et de l'accrocher chaque chaîne et de fuite sous-chaîne dans vos données.
Vous le nombre de nœuds dans la profondeur de premier ordre. Ensuite, vous pouvez créer une table avec un maximum de 255 lignes pour chacun de vos dossiers, avec l'Id de votre dossier, et de l'id de nœud dans votre arbre qui correspond à la chaîne de début ou de fin de chaîne. Puis, quand vous faites une recherche, vous trouverez l'id de nœud qui représente la chaîne de caractères que vous recherchez (et tous fuite sous-chaînes) et faites une plage de recherche.
si vous ne se soucient de stockage, vous pouvez créer une autre table avec partielle Titre des entrées, en commençant par chacune des sous-chaîne (jusqu'à 255 entrées conformément à la normale de titre ).
de cette façon, vous pouvez indexer ces sous-chaînes, et qui correspond au début de la chaîne, devrait grandement améliorer les performances.
Sons comme vous l'avez écarté toutes les bonnes alternatives.
Vous savez déjà que votre requête
de ne pas utiliser un index, il va faire un full table scan à chaque fois.
Si vous étiez sûr que la chaîne était à la début du champ, vous pourriez faire
qui serait un indice sur le Titre.
Êtes-vous sûr de recherche de texte intégral ne serait pas vous aider ici?
En fonction des besoins de votre entreprise, j'ai utilisé parfois la logique suivante:
LIKE 'abc%'
) tout d'abord, qui va utiliser un index.LIKE '%abc%'
)Dépend de ce que vous avez besoin, bien sûr, mais je l'ai utilisé dans des situations où je peux montrer la méthode la plus simple et la plus commune des résultats de la première, et ne se déplacent que sur de la plus difficile de la requête si nécessaire.
Vous pouvez ajouter une colonne calculée sur la table: titleLength comme len(titre) ont PERSISTÉ. Cela permettrait de stocker la longueur de la "titre" de la colonne. Créer un index sur cette.
Aussi, ajouter une autre colonne calculée appelé: ReverseTitle Inverse(titre) ont PERSISTÉ.
Maintenant, quand quelqu'un recherche un mot clé, vérifiez si la longueur du mot est la même que titlelength. Si oui, faites un "=" recherche. Si la longueur de mot-clé est inférieure à la longueur de la titleLength, puis procédez de l'une COMME. Mais d'abord, faire un titre COMME " abc%', puis faire un reverseTitle COMME " abc%'. Semblable à Brad approche - c'est à dire vous faire la prochaine difficile de requête uniquement si cela est nécessaire.
Aussi, si le 80-20 règles s'applique à vos mots clés/des sous-chaînes (c'est à dire si la plupart des recherches sont sur une minorité de mots-clés), alors vous pouvez aussi envisager de faire une sorte de mise en cache. Pour exemple: disons que vous avez trouvé que de nombreux utilisateurs de recherche pour le mot clé "abc" et ce mot-clé de recherche renvoie les enregistrements dont les id 20, 22, 24, 25 - vous pouvez stocker cela dans un tableau distinct et ont de ce indexés.
Et maintenant, quand quelqu'un recherche un nouveau mot-clé, vérifiez d'abord dans ce "cache" de la table pour voir si la recherche a été effectuée antérieurement par un utilisateur. Si oui, pas besoin de chercher de nouveau dans la table principale. Il suffit de retourner les résultats de "cache" de la table.
Vous pouvez également combiner les ci-dessus avec SQL Server TextSearch. (en supposant que vous avez une raison valable de ne pas l'utiliser). Mais vous pouvez néanmoins utiliser le Texte de la recherche d'abord à ma liste l'ensemble des résultats. et puis d'exécuter une requête SQL sur la table pour obtenir des résultats précis à l'aide de l'Id retourné par le Texte de Recherche comme paramètre le long de avec votre mot-clé.
Tout cela est évidemment en supposant que vous avez à l'utilisation de SQL. Si non, vous pouvez explorer quelque chose comme Apache Solr.
Créer des index de vue il y a une nouvelle fonctionnalité de sql create index sur la colonne que vous avez besoin de rechercher et d'utiliser ce point de vue après dans votre recherche qui permettra de donner plus d'un résultat plus rapide.
Le jeu de caractères influe sur le rendement de la recherche en raison de données
taille de la ram et le disque. Le goulot d'étranglement est souvent I/O.
votre champ char plutôt que la totalité du texte, qui est plus rapide. Ne pas
sélectionnez les colonnes inutiles dans votre instruction select.
Faire une chose, l'utilisation de la clé primaire sur colonne spécifique & index en cluster forme.
Puis recherche en utilisant n'importe quelle méthode (wild card ou = ou pas du tout), il recherche de façon optimale, car la table est déjà en forme, de sorte qu'il sait où il peut trouver (parce que la colonne est déjà trié forme)