등호(=) 대맘에 들다
할 때 SQL을 하면 어떤 ?=
순식간에WHERE
대신 절LIKE
?
연산자 , 특한연없이는자산별▁without는,없이▁operators▁any자산.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 매뉴얼의 이 페이지는 문자열 비교 함수라고 합니다.=
논의되지 않았으며, 이는 다음을 의미합니다.=
문자열 비교 함수는 엄밀하게는 아닙니다.
Does 방법=
일?
SQL Standard § 8.2는 다음과 같은 방법을 설명합니다.=
문자열 비교:
두 문자열의 비교는 다음과 같이 결정됩니다.
만약 X의 문자의 길이가 Y의 문자의 길이와 같지 않다면, 짧은 문자열은 하나 이상의 패드 문자의 오른쪽에 연결함으로써 긴 문자열의 길이로 확장된 자체의 복사본으로 효과적으로 대체됩니다.여기서 패드 문자는 CS를 기준으로 선택됩니다.CS가 NO PAD 속성을 가지고 있는 경우, 패드 문자는 CS 아래의 문자열보다 적게 조합하는 X와 Y의 문자 집합에 있는 어떤 문자와도 다른 구현 종속 문자입니다.그렇지 않으면 패드 문자는 <스페이스>입니다.
X와 Y의 비교 결과는 대조 시퀀스 CS에 의해 제공됩니다.
조합 순서에 따라 길이가 다르거나 문자 시퀀스가 다르더라도 두 문자열을 동일하게 비교할 수 있습니다.작업 MAX, MIN, DISTINCT, 그룹화 열 참조 및 UNION, EXCUST 및 ENTROSS 연산자가 문자열을 참조하는 경우 이러한 동일한 값 집합에서 이러한 작업에 의해 선택된 특정 값은 구현에 따라 달라집니다.
(강조 추가됨)
이것은 무엇을 의미합니까?그은문을비때할교자열것,때▁the,▁when▁strings할▁it,=
연산자는 현재 조합 주위의 얇은 래퍼일 뿐입니다.데이터 정렬은 문자열을 비교하기 위한 다양한 규칙이 있는 라이브러리입니다.다음은 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()
이 데이터 정렬은 한 번에 여러 바이트를 처리할 수 있으며 대소문자를 구분하지 않는 비교와 같은 다양한 변환을 적용할 수 있습니다. 그=
연산자가 조합의 변화로부터 완전히 추상화됩니다.
Does 방법LIKE
일?
SQL Standard » 8.5는 다음과 같은 방법을 설명합니다.LIKE
문자열 비교:
<예언>
M LIKE P
M을 다음과 같은 서브스트링으로 분할하는 경우 참입니다.
M의 부분 문자열은 M의 0개 이상의 연속적인 <문자 표현>의 시퀀스이며, M의 각 <문자 표현>은 정확히 하나의 부분 문자열의 일부입니다.
ii) 만약 P의 i번째 부분 문자열 지정자가 임의의 문자 지정자라면, M의 i번째 부분 문자열은 임의의 단일 <문자 표현>입니다.
iii) 만약 P의 i번째 부분 문자열 지정자가 임의의 문자열 지정자라면, M의 i번째 부분 문자열은 0 이상의 임의의 시퀀스입니다.
iv) 만약 P의 i번째 부분 문자열 지정자가 임의의 문자 지정자도 임의의 문자열 지정자도 아니라면, M의 i번째 부분 문자열은 <공백> 문자를 M에 추가하지 않고 <like 술어>의 조합 순서에 따라 해당 부분 문자열 지정자와 동일하며, 동일한 길이를 갖는다 하위 문자열 지정자입니다.
M의 서브스트링 수는 P의 서브스트링 지정자 수와 같습니다.
(강조 추가됨)
이것은 꽤 말이 많으니, 그것을 분해해 보겠습니다.항목 ii 및 iii는 와일드카드를 참조합니다._
그리고.%
각각 다음과 같다.한다면P
에는 와일드카드가 포함되어 있지 않으므로 항목 iv만 적용됩니다.이것은 OP가 제기한 관심 사례입니다.
이 경우 각 "부분 문자열"(개별 문자)을 비교합니다.M
에 있어서 각각의 부차적인 부분에 대하여.P
현재 데이터 정렬을 사용합니다.
결론들
결론은 문자열을 비교할 때=
을 비교하는 반면, 는 " " " 입니다.LIKE
한 번에 하나의 문자를 비교합니다.두 비교 모두 현재 조합을 사용합니다.이러한 차이는 이 게시물의 첫 번째 예에서 입증된 것처럼 경우에 따라 다른 결과로 이어집니다.
어떤 것을 사용해야 합니까?아무도 그것을 말할 수 없습니다. 사용 사례에 맞는 것을 사용해야 합니다.비교 연산자를 전환하여 너무 일찍 최적화하지 마십시오.
등호(=) 연산자는 "비교 연산자가 동일성에 대해 두 값을 비교"합니다.즉, SQL 문에서는 방정식의 양쪽이 동일하지 않으면 true가 반환되지 않습니다.예:
SELECT * FROM Store WHERE Quantity = 200;
LIKE 연산자는 "문자열 값과 와일드카드 문자가 포함된 패턴 문자열"을 일치시키는 "패턴 일치 비교"를 구현합니다.예:
SELECT * FROM Employees WHERE Name LIKE 'Chris%';
LIKE는 일반적으로 문자열에만 사용되며 동등한 것이 더 빠르다고 생각합니다.등호 연산자는 와일드카드 문자를 리터럴 문자로 처리합니다.반환되는 결과의 차이는 다음과 같습니다.
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 '좋아요' 대 '=' 성능에 대한 질문에 대한 다른 답변의 사본/복사본입니다.
mysql 5.5를 사용한 개인적인 예: 저는 2개의 테이블 사이에 내부 결합을 했습니다. 300만 행 중 하나와 10,000 행 중 하나입니다.
다음과 같은 인덱스에서 like를 사용할 때(와일드카드 없음) 약 30초가 소요되었습니다.
where login like '12345678'
'설명'을 사용하면 다음과 같이 알 수 있습니다.
동일한 쿼리에서 '='을 사용하는 경우 약 0.1초가 소요되었습니다.
where login ='12345678'
'설명'을 사용하면 다음을 알 수 있습니다.
보다시피,피시▁the▁as다보,.like
인덱스 검색을 완전히 취소했기 때문에 쿼리에 300배의 시간이 걸렸습니다.
LIKE
그리고.=
다릅니다. LIKE
검색 쿼리에 사용할 항목입니다.또한 다음과 같은 와일드카드도 허용합니다._
) 및 (문자 포함) »%
(다중 문자 와일드카드).
=
정확한 일치를 원한다면 사용해야 하며 더 빠를 것입니다.
LIKE와 함께 와일드카드를 사용할 수 있는 가능성을 제외하고 한 가지 차이점은 후행 공백입니다.= 연산자는 후행 공간을 무시하지만 LIKE는 무시하지 않습니다.
데이터베이스 시스템에 따라 다릅니다.
일반적으로 특수 문자가 없는 경우 예, = 및 LIKE는 동일합니다.
그러나 일부 데이터베이스 시스템은 연산자에 따라 데이터 정렬 설정을 다르게 처리할 수 있습니다.
예를 들어, MySQL과 =의 비교에서 문자열은 기본적으로 대소문자를 구분하지 않으므로 특수 문자가 없는 LIKE도 동일합니다.일부 다른 RDBMS의 LIKE는 대소문자를 구분하지 않는 반면 =는 대소문자를 구분하지 않습니다.
이 예에서 우리는 바르카르콜이 포함하지 않는 것을 당연하게 생각합니다.''
이 열에 빈. 열 빈 셀 없 습 니 다
select * from some_table where varcharCol = ''
select * from some_table where varcharCol like ''
첫 번째 행은 0 행 출력을 생성하고 두 번째 행은 전체 목록을 표시합니다.는 엄밀하게 일치하는 대/소문자인 반면, like는 필터와 같은 역할을 합니다. 필터에 기준이 없으면 모든 데이터가 유효합니다.
like - 그 목적 때문에 조금 더 느리게 작동하고 varchar 및 유사한 데이터와 함께 사용하도록 고안되었습니다.
=를 사용하면 런타임에 쿼리를 작성할 때 문자열에서 와일드카드 및 특수 문자 충돌을 방지할 수 있습니다.
이렇게 하면 LIKE 절에 들어갈 수 있는 특수 와일드카드 문자를 모두 이스케이프할 필요가 없고 의도한 결과를 생성하지 않으므로 프로그래머의 작업이 더 쉬워집니다.결국 =는 99%의 사용 사례 시나리오이기 때문에 매번 이러한 문제를 해결해야 하는 것은 괴로운 일입니다.
90년대에 눈을 굴린
저도 조금 더 느리다고 생각하지만 패턴에 와일드카드가 없다면 의미가 있을지 의문입니다.
정확하게 일치하는 항목을 검색하면 =와 LIKE를 모두 사용할 수 있습니다.
이 경우 "="를 사용하는 것이 조금 더 빠릅니다(정확하게 일치하는 경우가 많습니다). SQL Server Management Studio에서 동일한 쿼리를 두 번 사용하고, "="를 사용하고, "LIKE"를 한 번 사용한 다음, "Query" / "실제 실행 계획 포함"을 사용하여 직접 확인할 수 있습니다.
두 개의 쿼리를 실행하면 두 번의 결과와 두 개의 실제 실행 계획이 표시됩니다.제 경우에는 50%에서 50%로 분할되었지만, "=" 실행 계획은 가장 왼쪽에 있는 "SELECT" 상자 위에 마우스를 올려놓으면 나타나는 "세부 트리 비용"이 더 작습니다. 하지만 역시 큰 차이는 없습니다.
그러나 LIKE 식에 와일드카드를 사용하여 검색을 시작하면 검색 성능이 저하됩니다."LIKE Mill%" 검색은 여전히 매우 빠를 수 있습니다. SQL Server는 해당 열의 인덱스가 있는 경우 해당 열의 인덱스를 사용할 수 있습니다.SQL Server가 이 검색을 충족할 수 있는 유일한 방법은 전체 테이블 검색을 수행하는 것이기 때문에 "LIKE %expression%" 검색은 매우 느립니다.그러니 LIKE를 조심하세요!
마르크
성능과 관련된 원래 질문을 해결하려면 인덱스 활용률이 중요합니다.간단한 테이블 스캔이 발생하면 "LIKE"와 "="가 동일합니다.인덱스가 포함된 경우 LIKE 절이 형성되는 방식에 따라 달라집니다.보다 구체적으로 와일드카드의 위치는 어디입니까?
다음 사항을 고려합니다.
CREATE TABLE test(
txt_col varchar(10) NOT NULL
)
go
insert test (txt_col)
select CONVERT(varchar(10), row_number() over (order by (select 1))) r
from master..spt_values a, master..spt_values b
go
CREATE INDEX IX_test_data
ON test (txt_col);
go
--Turn on Show Execution Plan
set statistics io on
--A LIKE Clause with a wildcard at the beginning
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '%10000'
--Results in
--Table 'test'. Scan count 3, logical reads 15404, physical reads 2, read-ahead reads 15416, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index SCAN is 85% of Query Cost
--A LIKE Clause with a wildcard in the middle
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '1%99'
--Results in
--Table 'test'. Scan count 1, logical reads 3023, physical reads 3, read-ahead reads 3018, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost for test data, but it may result in a Table Scan depending on table size/structure
--A LIKE Clause with no wildcards
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO
--an "=" clause = does Index Seek same as above
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col = '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO
DROP TABLE test
또한 "="와 "LIKE"를 사용할 때 쿼리 계획을 만드는 데 있어 무시할 수 있는 차이가 있을 수 있습니다.
에, 드카외드에점, 른은다일의 .=
그리고.LIKE
SQL 서버 유형과 열 유형에 따라 달라집니다.
다음 예를 들어 보겠습니다.
CREATE TABLE testtable (
varchar_name VARCHAR(10),
char_name CHAR(10),
val INTEGER
);
INSERT INTO testtable(varchar_name, char_name, val)
VALUES ('A', 'A', 10), ('B', 'B', 20);
SELECT 'VarChar Eq Without Space', val FROM testtable WHERE varchar_name='A'
UNION ALL
SELECT 'VarChar Eq With Space', val FROM testtable WHERE varchar_name='A '
UNION ALL
SELECT 'VarChar Like Without Space', val FROM testtable WHERE varchar_name LIKE 'A'
UNION ALL
SELECT 'VarChar Like Space', val FROM testtable WHERE varchar_name LIKE 'A '
UNION ALL
SELECT 'Char Eq Without Space', val FROM testtable WHERE char_name='A'
UNION ALL
SELECT 'Char Eq With Space', val FROM testtable WHERE char_name='A '
UNION ALL
SELECT 'Char Like Without Space', val FROM testtable WHERE char_name LIKE 'A'
UNION ALL
SELECT 'Char Like With Space', val FROM testtable WHERE char_name LIKE 'A '
MS SQL Server 2012를 사용하면 다음 공간을 제외하고는 비교에서 무시됩니다.
LIKE
이 열 유 이 음 일 때 때VARCHAR
.MySQL 5.5를 사용하면 다음 시간 동안 후행 공백이 무시됩니다.
=
하지만 때문은 아닙니다.LIKE
함께CHAR
그리고.VARCHAR
.Postgre 사용SQL 9.1, 공간은 두 가지 모두에서 중요합니다.
=
그리고.LIKE
용사를VARCHAR
그나 아닌이와 함께는 .CHAR
(설명서 참조).이 있는 행동.
LIKE
는 또과는다다니릅과 다릅니다.CHAR
.으로 와동한터사용이, 적사용시명데일.
CAST
열 이름에도 차이가 있습니다.SELECT 'CAST none', val FROM testtable WHERE char_name LIKE 'A' UNION ALL SELECT 'CAST both', val FROM testtable WHERE CAST(char_name AS CHAR) LIKE CAST('A' AS CHAR) UNION ALL SELECT 'CAST col', val FROM testtable WHERE CAST(char_name AS CHAR) LIKE 'A' UNION ALL SELECT 'CAST value', val FROM testtable WHERE char_name LIKE CAST('A' AS CHAR)
이렇게 하면 "CAST both" 및 "CAST col"에 대한 행만 반환됩니다.
=
훨씬빠다보다 훨씬 .LIKE
.
11GB의 데이터와 1,000만 개 이상의 레코드를 사용하여 MySQL에서 테스트한 f_time 열은 인덱싱됩니다.
SELECT * FROM XXXXX WHERE f_time = '1621442261'
0.00초가 걸렸고 330개의 기록을 반환했습니다.
SELECT * FROM XXXXX WHERE f_time like '1621442261'
44.71초가 걸렸고 330개의 레코드를 반환했습니다.
실제로는 쿼리가 수행하기를 원하는 작업으로 귀결됩니다.정확한 일치를 의미하는 경우 =를 사용합니다.좀 더 퍼지한 매치를 말하는 거라면 LIKE를 사용하세요.당신이 의미하는 바를 말하는 것은 보통 코드가 있는 좋은 정책입니다.
LIKE 키워드에는 의심할 여지 없이 "성능 가격 태그"가 부착되어 있습니다.즉, 쿼리에 사용할 와일드카드 문자를 포함할 수 있는 입력 필드가 있으면 입력에 와일드카드 중 하나가 포함된 경우에만 LIKE를 사용하는 것이 좋습니다.그렇지 않으면 비교와 동일한 표준을 사용합니다.
잘 부탁드립니다...
Oracle에서 와일드카드가 없는 'like'는 'equals'와 동일한 결과를 반환하지만 추가 처리가 필요할 수 있습니다.Tom Kyte에 따르면 Oracle은 리터럴을 사용할 때 와일드카드가 없는 '좋아요'를 '평등'으로 취급하지만 바인딩 변수를 사용할 때는 그렇지 않습니다.
=
그리고.LIKE
동하않 다니습지일.
=
한 문자열 정한문일치니다와 합니다.LIKE
할 수 합니다.
언급URL : https://stackoverflow.com/questions/543580/equals-vs-like
'programing' 카테고리의 다른 글
UICollectionView 셀을 수평으로 중앙에 배치하는 방법은 무엇입니까? (0) | 2023.04.27 |
---|---|
MVVM 템플릿의 좋은 예 (0) | 2023.04.27 |
zure의 윈도우 서비스와 동등한 것은 무엇입니까? (0) | 2023.04.27 |
Git의 .classpath 및 .project 무시 (0) | 2023.04.27 |
Unix 콘솔 또는 Mac 터미널에서 셸 스크립트를 실행하는 방법은 무엇입니까? (0) | 2023.04.27 |