[sql] 같음 (=) 대 LIKE

SQL을 사용할 때 ? 대신 절 =에서 사용하면 어떤 이점 WHERELIKE있습니까?

특별한 연산자가 LIKE없고 =동일합니까?



답변

다른 연산자

LIKE그리고 =다른 사업자입니다. 여기에있는 대부분의 답변은 와일드 카드 지원에 중점을 두는데,이 연산자들 간의 유일한 차이점은 아닙니다!

=숫자와 문자열에서 작동하는 비교 연산자입니다. 문자열을 비교할 때 비교 연산자는 전체 문자열을 비교합니다 .

LIKE문자를 문자별로 비교하는 문자열 연산자입니다 .

문제를 복잡하게하기 위해 두 연산자 는 비교 결과에 중요한 영향을 줄 수 있는 데이터 정렬 을 사용합니다 .

동기 부여 예

먼저 이러한 연산자가 분명히 다른 결과를 생성하는 예를 살펴 보겠습니다. MySQL 매뉴얼에서 인용 할 수 있습니다.

SQL 표준에 따라 LIKE는 문자별로 일치를 수행하므로 = 비교 연산자와 다른 결과를 생성 할 수 있습니다.

mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
|                                    1 |
+--------------------------------------+

MySQL 매뉴얼의이 페이지는 String Comparison Functions 이며, =논의되지 않았으므로 이는 =엄격하게 문자열 비교 함수가 아니라는 것을 의미 합니다.

어떻게 =작동합니까?

SQL 표준 § 8.2 방법에 대해 설명 =문자열을 비교 :

두 문자열의 비교는 다음과 같이 결정됩니다.

a) X 문자의 길이가 Y 문자의 길이와 같지 않으면 짧은 문자열은 비교를 위해 긴 문자열의 길이로 확장 된 자체 사본으로 효과적으로 대체됩니다. 하나 이상의 패드 문자의 오른쪽에 연결하여 패드 문자가 CS를 기준으로 선택됩니다. CS에 NO PAD 속성이있는 경우 패드 문자는 X 및 Y의 문자 세트에있는 문자와 다른 구현 종속 문자이며 CS의 문자열보다 작게 대조됩니다. 그렇지 않으면 패드 문자는입니다.

b) X와 Y의 비교 결과는 조합 순서 CS에 의해 주어진다.

c) 조합 순서에 따라 두 문자열은 길이가 다르거 나 다른 문자 시퀀스를 포함하더라도 동일하게 비교 될 수 있습니다. MAX, MIN, DISTINCT, 그룹화 열을 참조하고 UNION, EXCEPT 및 INTERSECT 연산자가 문자열을 참조하는 경우 이러한 동일한 값 세트에서 이러한 조작에 의해 선택된 특정 값은 구현에 따라 다릅니다.

(공포도 추가됨)

이것은 무엇을 의미 하는가? 즉, 문자열을 비교할 때 =연산자는 현재 데이터 정렬 주위의 얇은 래퍼 일뿐입니다. 데이터 정렬은 문자열을 비교하기위한 다양한 규칙이있는 라이브러리입니다. 다음 은 MySQL의 이진 데이터 정렬 예입니다 .

static int my_strnncoll_binary(const CHARSET_INFO *cs __attribute__((unused)),
                               const uchar *s, size_t slen,
                               const uchar *t, size_t tlen,
                               my_bool t_is_prefix)
{
  size_t len= MY_MIN(slen,tlen);
  int cmp= memcmp(s,t,len);
  return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
}

이 특정 데이터 정렬은 바이트 단위를 비교하기 위해 발생합니다 (그래서 “이진”이라고 부릅니다. 문자열에 특별한 의미를 부여하지 않습니다). 다른 데이터 정렬은보다 고급 비교를 제공 할 수 있습니다.

예를 들어, 대소 문자를 구분하지 않는 비교를 지원 하는 UTF-8 데이터 정렬 이 있습니다. 코드가 너무 길어서 여기에 붙여 넣을 수는 없지만 해당 링크로 이동하여의 본문을 읽으십시오 my_strnncollsp_utf8mb4(). 이 데이터 정렬은 한 번에 여러 바이트를 처리 할 수 ​​있으며 대소 문자를 구분하지 않는 비교와 같은 다양한 변환을 적용 할 수 있습니다. =연산자는 완전히 정렬의 변덕으로부터 추출된다.

어떻게 LIKE작동합니까?

SQL 표준 § 8.5 방법에 대해 설명 LIKE문자열을 비교 :

<조건 자>

M LIKE P

M을 하위 문자열로 분할하는 경우 다음과 같습니다.

i) M의 서브 스트링은 M의 0 개 이상의 인접한 <문자 표현>의 시퀀스이며 M의 각 <문자 표현>은 정확히 하나의 서브 스트링의 일부입니다.

ii) P의 i 번째 서브 스트링 지정자가 임의의 문자 지정자 인 경우 M의 i 번째 서브 스트링은 임의의 단일 <문자 표현>입니다.

iii) P의 i 번째 서브 스트링 지정자가 임의의 스트링 지정자 인 경우, M의 i 번째 서브 스트링은 0 이상의 <문자 표현>의 임의의 시퀀스이다.

iv) P의 i 번째 서브 스트링 지정자가 임의의 문자 지정자 또는 임의의 스트링 지정자가 아닌 경우, M의 i 번째 서브 스트링은 <like predicate>의 조합 순서에 따라 해당 서브 스트링 지정자와 동일합니다. <space> 문자를 M에 추가하고 하위 문자열 지정자와 길이가 같습니다.

v) M의 서브 스트링 수는 P의 서브 스트링 지정자 수와 같습니다.

(공포도 추가됨)

이것은 꽤 말이 많으므로 세분화합시다. 항목 ii 및 iii은 각각 와일드 카드 _%을 나타냅니다. 경우 P어떤 와일드 카드를 포함하지 않는, 만 항목 IV이 적용됩니다. 이것은 OP가 제기 한 관심사입니다.

이 경우 현재 데이터 정렬 MP사용하여 각 “하위 문자열”(개별 문자)을 각 하위 문자열과 비교합니다 .

결론

결론은 =문자열을 LIKE비교할 때 한 번에 한 문자 를 비교 하면서 전체 문자열을 비교한다는 것입니다. 두 비교는 모두 현재 데이터 정렬을 사용합니다. 이 게시물의 첫 번째 예에서 알 수 있듯이이 차이는 경우에 따라 다른 결과로 이어집니다.

어느 것을 사용해야합니까? 아무도 당신에게 말할 수 없습니다. 사용 사례에 맞는 것을 사용해야합니다. 비교 연산자를 전환하여 조기에 최적화하지 마십시오.


답변

equals (=) 연산자는 “비교 연산자가 두 값의 동등성을 비교합니다”입니다. 즉, SQL 문에서 방정식의 양변이 같지 않으면 참을 리턴하지 않습니다. 예를 들면 다음과 같습니다.

SELECT * FROM Store WHERE Quantity = 200;

LIKE 연산자는 “패턴 일치 비교를 구현하여” “와일드 카드 문자를 포함하는 패턴 문자열과 문자열 값을 일치 시키려고 시도합니다.” 예를 들면 다음과 같습니다.

SELECT * FROM Employees WHERE Name LIKE 'Chris%';

LIKE는 일반적으로 문자열에만 사용되며 같음 (더 이상은 빠릅니다). equals 연산자는 와일드 카드 문자를 리터럴 문자로 취급합니다. 반환 된 결과의 차이는 다음과 같습니다.

SELECT * FROM Employees WHERE Name = 'Chris';

SELECT * FROM Employees WHERE Name LIKE 'Chris';

LIKE를 사용하면 일반적으로 패턴 일치로 시간이 더 걸리지 만 동일한 결과를 반환합니다. 하나,

SELECT * FROM Employees WHERE Name = 'Chris%';

SELECT * FROM Employees WHERE Name LIKE 'Chris%';

“=”를 사용하면 “Chris %”가 반환 된 결과 만 나오고 LIKE 연산자는 “Chris”로 시작하는 모든 것을 반환하는 다른 결과를 반환합니다.

희망이 도움이됩니다. 좋은 정보는 여기 에서 찾을 수 있습니다 .


답변

이것은 질문 SQL ‘like’vs ‘=’성능 에 대한 또 다른 대답의 복사 / 붙여 넣기입니다 .

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

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

where login like '12345678'

‘설명’을 사용하면 다음과 같은 결과를 얻습니다.

여기에 이미지 설명을 입력하십시오

동일한 쿼리에서 ‘=’를 사용하는 경우 약 0.1 초가 걸렸습니다.

where login ='12345678'

‘설명’을 사용하면 다음과 같은 결과를 얻습니다.

여기에 이미지 설명을 입력하십시오

보시다시피, like완전히 검색된 인덱스 탐색은 쿼리 시간이 300 배 더 걸렸습니다.


답변

LIKE그리고 =다릅니다. LIKE검색어에 사용할 것입니다. 또한 _(단순 문자 와일드 카드) 및 %(다중 문자 와일드 카드)와 같은 와일드 카드도 허용 합니다.

= 정확한 일치를 원하면 더 빠를 것입니다.

이 사이트는 설명합니다 LIKE


답변

LIKE와 함께 와일드 카드를 사용할 수있는 가능성과는 다른 한 가지 차이점은 후행 공백입니다. = 연산자는 후행 공백을 무시하지만 LIKE는 그렇지 않습니다.


답변

데이터베이스 시스템에 따라 다릅니다.

일반적으로 특수 문자가 없으면 yes, = 및 LIKE가 동일합니다.

그러나 일부 데이터베이스 시스템은 조합 설정을 다른 연산자와 다르게 처리 할 수 ​​있습니다.

예를 들어 MySQL에서 = on strings 비교는 기본적으로 대소 문자를 구분하지 않으므로 특수 문자가없는 LIKE는 동일합니다. 다른 RDBMS의 LIKE는 대소 문자를 구분하지 않지만 =는 그렇지 않습니다.


답변

이 예에서는 varcharcol ''에이 열에 대해 빈 셀이없고 비어 있지 않은 것으로 간주합니다.

select * from some_table where varcharCol = ''
select * from some_table where varcharCol like ''

첫 번째 결과는 0 행 출력이고 두 번째 결과는 전체 목록을 표시합니다. =는 필터와 같은 역할을하는 반면 엄격하게 일치하는 경우입니다. 필터에 기준이 없으면 모든 데이터가 유효합니다.

-그 목적으로 인해 조금 느리게 작동하며 varchar 및 유사한 데이터와 함께 사용하기위한 것입니다.