[sql] SQL ‘like’vs ‘=’성능

이 질문은 내가 궁금한 점을 둘러싸고 있지만 대답이 정확히 다루지는 않습니다.

것으로 보인다 일반적으로 ‘=’보다 빠른 와일드 카드를 사용하는 경우 ‘와 같은’입니다. 이것은 일반적인 통념으로 보입니다. 그러나 제한된 수의 다른 고정, 하드 코딩 된 varchar 식별자를 포함하는 열이 있고 그중 하나와 일치하는 모든 행을 선택한다고 가정 해 보겠습니다.

select * from table where value like 'abc%'

select * from table where value = 'abcdefghijklmn'

‘좋아요’는 일치 항목을 찾기 위해 처음 세 문자 만 테스트해야하는 반면 ‘=’는 전체 문자열을 비교해야합니다. 이 경우 ‘좋아요’는 다른 모든 것이 동등하다는 장점이있는 것처럼 보입니다.

이것은 일반적이고 학문적 인 질문을위한 것이므로 어떤 DB를 사용하든 상관 없지만 SQL Server 2005를 사용하여 발생했습니다.



답변

참조 https://web.archive.org/web/20150209022016/http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx를

거기에서 인용 :

LIKE의 인덱스 사용 규칙은 대략 다음과 같습니다.

  • 필터 기준이 =를 사용하고 필드가 인덱싱 된 경우 대부분 INDEX / CLUSTERED INDEX SEEK를 사용합니다.

  • 필터 기준이 와일드 카드없이 LIKE를 사용하는 경우 (예 : 웹 보고서에 %가있을 수 있지만 대신 전체 문자열을 사용하는 매개 변수가있는 경우) 인덱스를 사용할 가능성이 # 1 정도입니다. 증가 된 비용은 거의 아무것도 아닙니다.

  • 필터 기준이 LIKE를 사용하지만 처음에 와일드 카드가있는 경우 (Name0 LIKE ‘% UTER’에서와 같이) 인덱스를 사용할 가능성이 훨씬 적지 만 여전히 전체 또는 부분 범위에서 INDEX SCAN을 수행 할 수 있습니다. 색인.

  • 그러나 필터 기준이 LIKE를 사용하지만 STRING FIRST로 시작하고 그 이후 어딘가에 와일드 카드가있는 경우 (Name0 LIKE ‘COMP % ER’에서와 같이) SQL은 INDEX SEEK를 사용하여 먼저 동일한 행을 빠르게 찾을 수 있습니다. 시작 문자를 입력 한 다음 해당 행에서 정확히 일치하는 항목을 찾습니다.

(또한 SQL 엔진은 쿼리에서 진행되는 다른 작업과 조인하려는 테이블에 따라 예상 한 방식으로 인덱스를 사용하지 않을 수도 있습니다. SQL 엔진은 가장 효율적이고 INDEX SEEK 대신 INDEX SCAN을 포함 할 수있는 방식으로 데이터를 가져 오기 위해 약간 쿼리)


답변

측정 가능한 차이입니다.

다음을 실행하십시오.

Create Table #TempTester (id int, col1 varchar(20), value varchar(20))
go

INSERT INTO #TempTester (id, col1, value)
VALUES
(1, 'this is #1', 'abcdefghij')
GO

INSERT INTO #TempTester (id, col1, value)
VALUES
(2, 'this is #2', 'foob'),
(3, 'this is #3', 'abdefghic'),
(4, 'this is #4', 'other'),
(5, 'this is #5', 'zyx'),
(6, 'this is #6', 'zyx'),
(7, 'this is #7', 'zyx'),
(8, 'this is #8', 'klm'),
(9, 'this is #9', 'klm'),
(10, 'this is #10', 'zyx')
GO 10000

CREATE CLUSTERED INDEX ixId ON #TempTester(id)CREATE CLUSTERED INDEX ixId ON #TempTester(id)

CREATE NONCLUSTERED INDEX ixTesting ON #TempTester(value)

그때:

SET SHOWPLAN_XML ON

그때:

SELECT * FROM #TempTester WHERE value LIKE 'abc%'

SELECT * FROM #TempTester WHERE value = 'abcdefghij'

결과 실행 계획은 첫 번째 작업 인 LIKE비교의 비용이 비교 보다 약 10 배 더 비싸다는 것을 =보여줍니다.

=비교 를 사용할 수 있다면 그렇게하십시오.


답변

또한을 사용할 때 like일부 SQL 버전은 인덱스를 무시하므로 성능이 저하됩니다. 예와 같이 “다음으로 시작”패턴을 사용하지 않는 경우 특히 그렇습니다.

쿼리에 대한 실행 계획을 실제로보고 그것이 무엇을하는지 확인해야하며 가능한 한 적게 추측해야합니다.

즉, “시작”패턴은 SQL Server에서 최적화 될 수 있으며 최적화됩니다. 그것은 것입니다 테이블 인덱스를 사용합니다. EF 4.0로 전환 like을위한 StartsWith바로이 이유.


답변

경우 value인덱싱되지 않은되며, 테이블 스캔 모두 결과. 이 시나리오의 성능 차이는 무시할 수 있습니다.

value인덱싱 된 경우 Daniel이 그의 의견에서 지적했듯이 =O (log N) 성능 인 인덱스 조회가 발생합니다. 등을 것이다 – 인덱스의 부분 스캔 결과 (가장 가능성이 얼마나 선택에 따라) >= 'abc'하고 < 'abd'있는가보다 더 많은 노력이 필요합니다 =.

여기서는 SQL Server에 대해 이야기하고 있습니다. 모든 DBMS가 LIKE에 적합하지는 않습니다.


답변

당신은 잘못된 질문을하고 있습니다. 데이터베이스에 문제가 항상이다 운영자 성능하지 SARGability 식의, 그리고 coverability 전체 쿼리. 운영자 자체의 성능은 거의 관련이 없습니다.

그럼, 어떻게 할 LIKE=SARGability의 측면에서 비교? LIKE, 상수로 시작하지 않는 표현식과 함께 사용되는 경우 (예 : 사용될 때 LIKE '%something') 정의상 비 SARGabale입니다. 그러나 그것은 만들 =거나 LIKE 'something%'SARGable합니까? 아니요. SQL 성능에 대한 모든 질문과 마찬가지로 대답은 텍스트 쿼리가 아니라 배포 된 스키마에 있습니다. 이러한 표현식 이를 충족하는 인덱스가 있는 경우 SARGable 있습니다 .

그래서, 진실 사이의 작은 차이가, 말 할 수 =및이 LIKE. 그러나 SQL에서 한 연산자 또는 다른 연산자가 ‘더 빠르다’고 묻는 것은 ‘빨리가는 것은 무엇입니까, 빨간 차 또는 파란 차?’와 같습니다. 색상이 아니라 엔진 크기와 차량 무게에 대해 질문해야합니다. 관계형 테이블 최적화에 대한 질문에 접근하려면 WHERE 절 (및 기타 절 )의 인덱스표현식 을 살펴 봐야합니다. WHERE로 시작).


답변

mysql 5.5를 사용한 개인적인 예 : 2 개의 테이블, 3 백만 행 중 하나와 10,000 행 중 하나 사이에 내부 조인이있었습니다.

아래와 같이 인덱스에 like를 사용할 때 (와일드 카드 없음) 약 30 초가 소요되었습니다.

where login like '12345678'

‘설명’을 사용하면 다음을 얻습니다.

여기에 이미지 설명 입력

동일한 쿼리에 ‘=’를 사용하면 약 0.1 초가 걸립니다.

where login ='600009'

‘설명’을 사용하면 다음을 얻습니다.

여기에 이미지 설명 입력

보시다시피 like인덱스 탐색 이 완전히 취소되었으므로 쿼리에 300 배 더 많은 시간이 소요되었습니다.


답변

전체 텍스트 검색을 찾고 계실 것 입니다.

전체 텍스트 검색과 달리 LIKE Transact-SQL 조건자는 문자 패턴에서만 작동합니다. 또한 LIKE 술어를 사용하여 형식화 된 2 진 데이터를 쿼리 할 수 ​​없습니다. 또한 많은 양의 구조화되지 않은 텍스트 데이터에 대한 LIKE 쿼리는 동일한 데이터에 대한 동등한 전체 텍스트 쿼리보다 훨씬 느립니다 . 수백만 행의 텍스트 데이터에 대한 LIKE 쿼리는 반환하는 데 몇 분이 걸릴 수 있습니다. 반면 전체 텍스트 쿼리는 반환되는 행 수에 따라 동일한 데이터에 대해 몇 초 이하 만 소요될 수 있습니다.