2013-04-14 21 views
-2

J'utilise le serveur SQL et ont une table avec 2 colonnes
myId varchar(80)
cchunk varchar(max)SQL Select est très lent avec CHARINDEX

Basiquement il stocke un grand morceau de texte pour c'est pourquoi je en ai besoin varchar(max). Mon problème est quand je fais une requête comme ceci:

select * 
from tbchunks 
where 
    (CHARINDEX('mystring1',tbchunks.cchunk)< CHARINDEX('mystring2',tbchunks.cchunk)) 
AND 
    CHARINDEX('mystring2',tbchunks.cchunk) - CHARINDEX('mystring1',tbchunks.cchunk) <=10 

Il faut 3 secondes pour terminer, et les morceaux de table est d'environ seulement 500 000 enregistrements et données renvoyées de la requête ci-dessus est partout entre 0 à 800 max J'ai un index non clusterisé sur la colonne myid, cela m'a aidé à faire le décompte rapide (*) mais n'a pas aidé avec la requête ci-dessus.

J'ai essayé d'utiliser Fulltext mais j'étais lent. J'ai essayé de scinder le texte en cchunk en parties plus petites et en ajoutant une colonne id qui reliera tous ces morceaux séparés, mais a fini avec une table avec 2 millions d'enregistrements de morceaux séparés de texte (je l'ai fait pour que je puisse ajouter index) la requête était encore plus lente.

EDIT: modifié la table pour inclure une clé primaire (int) créé fultext catalogue avec "Accent senstive = true" créé l'index de texte intégral sur mon Tabe sur la colonne "cchunk" couru la même requête ci-dessus et a fini par prendre 22 secondes avec est beaucoup plus lent

MISE à JOUR Merci à tous pour suggérer la FullText (Bertrand @ Aaron merci!), je me suis converti ma requête à ce

SELECT * DE tbchunksAS FT_TBL INNER JOIN CONTAINSTABLE (tbchunks, cchunk, '(LaChaine1 PRES LaChaine2)') AS KEY_TBL SUR FT_TBL.cID = KEY_TBL. [KEY]

par la façon dont le cid est la clé primaire i ajouté plus tard. de toute façon je reçois des résultats Borad et je remarque que plus la colonne RANK qui a été retourné le mieux les résultats. Ma question est quand RANK commence à être précis?

+4

Eh bien, avez-vous pensé [texte intégral Recherche] (http://msdn.microsoft.com/en- us/library/ms142571.aspx) et en le configurant correctement?Dire que vous l'avez "essayé et il était lent" ne donne pas l'assurance que vous avez correctement créé le catalogue, rempli correctement un ou plusieurs index, exécuté la bonne requête sur les données pour obtenir des résultats de recherche de proximité précis et efficaces, etc. de temps avez-vous passé avec la recherche de texte intégral exactement? –

+0

pas si longtemps, je viens de mettre en place le catalogue et l'a testé et était lent, donc j'ai oublié à ce sujet. De toute façon vais-je être en mesure d'utiliser charindex? – user2280232

+4

Je conduisais une Porsche la semaine dernière et c'était plus lent que la Nissan de ma femme. Oh j'ai oublié de mentionner qu'il y avait une bouteille de bière logée sous la pédale d'accélérateur! Il est difficile de vous dire pourquoi la recherche en texte intégral a été plus lente si nous n'avons aucune idée de la façon dont vous l'avez configurée et des requêtes que vous avez lancées. –

Répondre

1

Bien que les idées présentées ici soient parfaites, aucun organisme n'a réussi à vraiment résoudre mon problème, mais plutôt fourni des conseils utiles qui m'ont conduit à la solution que j'aimerais partager. Utiliser le texte intégral était vraiment la réponse comme beaucoup mentionné mais j'ai réussi à utiliser le Contient en combinaison avec Proche afin qu'il puisse totalement remplacer ma requête SQL actuelle et fournir une vitesse impressionnante.

CONTIENT (tbchunks, 'PRES ((LaChaine1, LaChaine2), 3, TRUE)')

+0

L'équivalent de ceci pour CHARINDEX est CONTAINS (tbchunks, 'NEAR ((mystring1, mystring2), 0, TRUE)') - qui correspond à "mystring1 mystring2" avec exactement un espace entre – snez

2

Un index ne va pas du tout aider avec CHARINDEX. Un index sur une colonne particulière ne sera capable de trouver rapidement des lignes où la valeur dans le champ indexé est exactement une valeur indexée. Je suis en fait assez surpris que la requête ne prenne que 3 secondes étant donné qu'elle doit lire chaque ligne quatre fois (ou au moins, deux fois).

+0

oui donc qu'est-ce que vous proposez alors? – user2280232

+0

Un index peut, dans la mesure où il réduit les E/S, augmenter les performances de certaines requêtes.Si la table en question avait des lignes plus grandes alors tous les 'cchunk' Les valeurs peuvent être lues plus rapidement en utilisant un index au lieu des pages de données. Peu susceptible d'aider beaucoup dans le cas spécifique du PO. Un [cover index] (http://stackoverflow.com/questions/609343/what-are-covering-indexes-and-covered-illes-in-sql-server) peut faire des choses surprenantes dans le bon environnement. – HABO