SQL Server의 LIKE vs CONTAINS


210

다음 쿼리 중 어느 것이 더 빠릅니까 (LIKE vs CONTAINS)?

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

또는

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

12
대답을 받아들이겠습니까?
AgentFire

7
그는 몇 년 동안 사람이 없었습니다.
Chris

답변:


174

두 번째 (당신이 의미 CONTAINS하고 실제로 유효한 쿼리에 넣었다고 가정 )는 어떤 형태의 색인 (이 경우 전체 텍스트 색인)을 사용할 수 있기 때문에 더 빠릅니다 . 물론이 쿼리 형식은 열이 전체 텍스트 인덱스 인 경우 에만 사용할 수 있습니다 . 그렇지 않은 경우 첫 번째 양식 만 사용할 수 있습니다.

LIKE를 사용하는 첫 번째 쿼리는 와일드 카드로 시작하기 때문에 인덱스를 사용할 수 없으므로 항상 전체 테이블 스캔이 필요합니다.


CONTAINS쿼리해야합니다 :

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

@edze-내 첫 번째 언급으로 이미 연결된 동일한 페이지를 의미 CONTAINS합니까? 무엇입니까? 질문의 원래 형태는 Column CONTAIN("%test%",Column)>0유효에 가까운 곳에 없었습니다. 아직 완전하지 않습니다.
Damien_The_Unbeliever

이를 통해 SharePoint에서 쿼리를 정렬 할 수있었습니다. 다른 위대한 답변 배지를 갖습니다.
ouflak

14

SQL Server 2012 인스턴스에서 두 쿼리를 모두 실행하면 첫 번째 쿼리가 제 경우 가장 빠르다는 것을 확인할 수 있습니다.

LIKE키워드가 포함 된 쿼리 에 클러스터 된 인덱스 스캔이 표시되었습니다.

CONTAINS또한 전체 텍스트 검색을위한 추가 사업자와 클러스터 인덱스 스캔을했고 병합 조인.

계획


8
클러스터 된 인덱스 리프 페이지 테이블입니다. LIKE선행 와일드 카드가 포함 된 쿼리는 인덱스 부분을 효율적으로 사용할 수 없습니다. 모든 것을 스캔하면됩니다. 의심 할 여지없이 전체 CI 스캔이 전체 텍스트 인덱스를 사용하는 쿼리보다 성능이 더 좋은 상황이있을 수 있지만 (예를 들어, 매우 많은 행이 일치하는 경우) 이는 일반적으로 "확인할 수있는 일부 규칙이 아닌 예외입니다" ".
Martin Smith

200,000 개가 넘는 레코드를 가져 오는 실제 실행 계획을보고 있습니다. 두 쿼리를 모두 일괄 처리하면 클러스터형 인덱스가 검색되지만 "CONTAINS"쿼리에는 추가 텍스트 비용과 병합 조인이 추가됩니다.
MI C

병합 조인을 선택하면 SQL Server에서 행의 x % 이상을 추정하여 조건 자와 일치하게됩니다. (여기서 X = 티핑 포인트 ). 이 경우 두 가지 모두 균등하게 일치 할 수 있다고 생각합니다. 실행 계획에 표시된 비용은 추정치입니다 (실제 계획에서도). FT 계획에 추가 실행 계획 운영자가 있지만 몇 가지 이점이 있습니다. 병합 조인은 FT 결과가 부족할 때 스캔이 끝나기 전에 중지 될 수 있으며 또한을 평가할 필요가 없습니다 LIKE.
마틴 스미스

1
SQL 2012에서 실행 계획을 확인하기 위해 비슷한 쿼리를 실행했으며 Index Seek을 제공했습니다. 어쩌면 여기의 예에서 테이블이 거의 비어있을 수 있습니다. 어떤 경우에는 SQL이 더 빠르기 때문에 인덱스를 사용하기 위해 아주 작은 테이블에서 인덱스 스캔을 사용합니다.
Juan

8

쿼리에 대시 ( "-")가 있기 때문에 CONTAINS시간이 오래 Merge걸리고 사용 되었다고 생각 합니다.adventure-works.com .

대시는 분리 단어이므로 CONTAINS검색 하고 결과를 adventure검색 works.com하고 병합하는 것보다 전체 텍스트 색인을 검색했습니다 .


8

또한 다음과 같이 변경하십시오.

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

이에:

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

전자는 " 이것은 테스트입니다 "및 " 테스트 케이스는 계획입니다 "와 같은 값을 가진 레코드를 찾습니다. .

후자는 또한 " 나는 이것을 테스트하고있다 "그리고 " 이것은 가장 크다 " 와 같은 값을 가진 레코드를 찾을 것이다 .


4
검색어 앞뒤에 별표를 표시합니까? 에 대한 문서를 읽을 때 CONTAINS' test'와 같은 접두어가 아닌 'test *'와 같은 접두어 용어 만 사용 하고 '* test ' 와 같은 전체 하위 문자열 검색은 언급하지 않습니다 . 그래도 시도하지 않았습니다.
matt forsythe

5
CONTAINS ( docs.microsoft.com/en-us/sql/t-sql/queries/… )에 대한 설명서를 읽으면 접두사 검색 만 지원됩니다. 나는 이것을 실험적으로 여러 번 시도했지만 Contains (Column, ' " test "')를 사용 하여 "이것이 가장 큰 것"(SQL 서버에서)을 찾을 수 없습니다.
cl0rkster
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.