web-dev-qa-db-fra.com

Meilleure approche pour "LIKE OR LIKE, OR LIKE, OR LIKE, OR = COMME "

Dans cette question il a le même problème que moi. J'ai besoin de quelque chose comme:

select * from blablabla 
where product 
like '%rock%' or
like '%paper%' or
like '%scisor%' or
like '%car%' or
like '%pasta%' 

C'est moche et cela n'utilise pas d'index. Dans ce cas, c'est vraiment la seule façon de le faire (pour sélectionner plusieurs mots dans une chaîne), ou dois-je utiliser FULLTEXT?

Si je comprends bien, avec le texte intégral, je peux sélectionner plusieurs mots dans une chaîne.

Cette question parle également du texte intégral

10
Racer SQL

Les index de texte intégral ne sont généralement pas une solution miracle et nécessitent une maintenance supplémentaire, de l'espace disque et des modifications assez intrusives des modèles de requête.

À moins que vous n'ayez vraiment besoin d'indexer des documents volumineux (pensez aux corps d'e-mails, aux PDF, aux documents Word, etc.), ils sont excessifs (et si nous sommes honnêtes, je supprimerais complètement ce processus de SQL Server et utilisez Elasticsearch ou quelque chose de similaire).

Pour les cas d'utilisation plus petits, les colonnes calculées sont généralement une meilleure approche.

Voici une configuration de démonstration rapide:

use tempdb

CREATE TABLE #fulltextindexesarestupid (Id INT PRIMARY KEY CLUSTERED, StopAbusingFeatures VARCHAR(100))

INSERT #fulltextindexesarestupid (Id)
SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY (@@ROWCOUNT))
FROM sys.messages AS m
CROSS JOIN sys.messages AS m2

UPDATE #fulltextindexesarestupid
SET StopAbusingFeatures = CASE WHEN Id % 15 = 0 THEN 'Bad'
                               WHEN Id % 3 = 0 THEN 'Idea'
                               WHEN Id % 5 = 0 THEN 'Jeans'
                               END


ALTER TABLE #fulltextindexesarestupid 
ADD LessBad AS CONVERT(BIT, CASE WHEN StopAbusingFeatures LIKE '%Bad%' THEN 1
                    WHEN StopAbusingFeatures LIKE '%Idea%' THEN 1
                    ELSE 0 END)

CREATE UNIQUE NONCLUSTERED INDEX ix_whatever ON #fulltextindexesarestupid (LessBad, Id)

L'interrogation basée sur même une colonne non persistante nous donne un plan qui "utilise des index" et tout :)

SELECT COUNT(*)
FROM #fulltextindexesarestupid AS f
WHERE LessBad = 1

NUTS

17
Erik Darling