web-dev-qa-db-fra.com

LIKE vs CONTAINS sur SQL Server

Laquelle des requêtes suivantes est plus rapide (LIKE vs CONTAINS)?

SELECT * FROM table WHERE Column LIKE '%test%';

ou

SELECT * FROM table WHERE Contains(Column, "test");
178
user667429

La seconde (en supposant que vous signifiiez CONTAINS , et la placez dans une requête valide) devrait être plus rapide, car elle peut utiliser un peu sous forme d’index (dans ce cas, un index en texte intégral). Bien entendu, cette forme de requête n'est disponible que si la colonne est dans un index de texte intégral. Si ce n'est pas le cas, seul le premier formulaire est disponible.

La première requête, utilisant LIKE, ne pourra pas utiliser d'index, car elle commence par un caractère générique et nécessite donc toujours une analyse complète de la table.


La requête CONTAINS doit être:

SELECT * FROM table WHERE CONTAINS(Column, 'test');
145

CONTIENT Recherche des correspondances précises ou floues (moins précises) avec des mots et expressions simples, des mots situés à une certaine distance les uns des autres ou des correspondances pondérées dans SQL Server.

CONTAINS peut rechercher:

  1. Un mot ou une phrase.
  2. Le préfixe d'un mot ou d'une phrase.
  3. Un mot près d'un autre mot.
  4. Un mot généré par inflexion à partir d'un autre (par exemple, le lecteur Word est la racine inflexionnelle de lecteurs, a conduit, conduit et conduit).
  5. Un mot qui est synonyme d'un autre mot utilisant un thésaurus (par exemple, le mot "métal" peut avoir des synonymes tels que "aluminium" et "acier").

Remarque: CONTAINS est plus rapide et fonctionnera s’il existe un index de recherche en texte intégral mis à jour. Si vous voulez une correspondance d’expression régulière exacte, vous pouvez utiliser la méthode similaire.

23
Somnath Muluk

Ayant exécuté les deux requêtes sur une instance SQL Server 2012, je peux confirmer que la première requête a été la plus rapide dans mon cas.

La requête avec le mot clé LIKE a montré une analyse d'index en cluster.

CONTAINS avait également une analyse d'index en cluster avec des opérateurs supplémentaires pour la correspondance de texte intégral et une jointure de fusion.

Plan

13
MI C

Essayez également de changer à partir de ceci:

    SELECT * FROM table WHERE Contains(Column, "test") > 0;

Pour ça:

    SELECT * FROM table WHERE Contains(Column, '"*test*"') > 0;

Les premiers trouveront des enregistrements avec des valeurs telles que "ceci est un test" et "n test est le plan".

Ce dernier trouvera également des enregistrements avec des valeurs telles que "je teste cela" et "c'est le plus grand".

5
John Doe

Je pense que CONTAINS a pris plus de temps et utilisé Merge parce que vous aviez un tiret ("-") dans votre requête adventure-works.com.

Le tiret est un mot de rupture. Ainsi, CONTAINS a recherché l'index de texte intégral pour adventure, puis il a recherché works.com et a fusionné les résultats.

5
Omri Valfer