LIKE는 어떻게 구현됩니까?


22

현재 데이터베이스 시스템 (예 : MySQL 또는 Postgres)에서 LIKE 연산자가 어떻게 구현되는지 설명 할 수 있습니까? 또는 그것을 설명하는 참고 문헌을 알려주십시오.

순진한 접근 방식은 각 레코드를 검사하여 관심있는 분야에서 정규 표현식 또는 부분 문자열 일치를 실행하는 것이지만 이러한 시스템이 더 똑똑한 일이라고 생각합니다.

답변:


19

아뇨, 그건 그들이하는 일과 거의 같습니다. 이제 선행 와일드 카드가없고 필드가 색인화되는 경우 (일반적인 상황) 데이터베이스 엔진은 정규식을 색인에 적용 할 수 있습니다. 예를 들어

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

데이터베이스는 색인 on LAST_NAME을 사용하여 성이 'Cav'로 시작하는 모든 행을 찾을 수 있습니다 . 반면에, 당신이 같은 것을 가지고 있다면

SELECT *
  FROM employees
 WHERE last_name LIKE '%av%'

데이터베이스는 전체 테이블 (또는 전체 인덱스)을 스캔하고 전체 LAST_NAME값 과 비교하여 표현식을 평가해야 합니다. 분명히, 그것은 매우 비싸다.

더 나은 관계형 데이터베이스는 대부분 서로 다른 종류의 인덱스와 텍스트 카탈로그를 구성하여보다 효율적인 방식으로 전체 텍스트 검색을 수행 할 수있는 기능이 있지만 LIKE 키워드는 사용하지 않습니다. 예를 들어, PostgreSQL의 전체 텍스트 검색에 대해 설명하는 좋은 기사가 있습니다.


4
오라클은 최고 퍼센트로도 인덱스를 사용할 수 있습니다. 검색되는 데이터가 행의 작은 하위 집합을 나타내는 경우 힌트를 사용하면 인덱스를 사용하여 실행 속도를 높일 수 있습니다. laurentschneider.com/wordpress/2009/07/…를 참조하십시오 .
레이 리펠

1
"전체 테이블을 스캔하십시오 ... 분명히, 그것은 매우 비쌉니다."-그것은 오히려 테이블에 달려 LAST_NAME있습니다. pps이 답변은 데이터베이스 시스템이 디스크 및 B- 트리 인덱스의 연속 스토리지에 기반한다고 가정합니까?
onedaywhen

26

저스틴 동굴 쓴뿐만 아니라, 이후 PostgreSQL의 9.1 당신이 속도를 높일 수 있는 과 검색 LIKE( ~~) 또는 ILIKE( ~~*도), 기본 정규 표현식 일치 ( ~). pg_trgm 모듈 이 GIN 또는 GiST 인덱스와 함께 제공하는 연산자 클래스를 사용하여 LIKE고정되지 않은 표현식의 속도를 높 입니다. 확장을 설치하려면 데이터베이스마다 한 번씩 실행하십시오.

CREATE EXTENSION pg_trgm;

양식의 색인 작성

CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);

또는:

CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);

GIN 또는 GiST 인덱스를 생성하고 유지 관리하는 데는 비용이 들지만 테이블을 많이 쓰지 않으면 큰 기능입니다.

Depesz 는 그의 블로그에서 새로운 기능에 대한 훌륭한 기사 를 작성했습니다 .

GIN 또는 GiST?

매뉴얼 의이 두 인용문은 약간의 지침을 제공해야합니다.

GiST와 GIN 색인 사이의 선택은 다른 곳에서 논의되는 GiST와 GIN의 상대적인 성능 특성에 따라 다릅니다. 일반적으로 GIN 인덱스는 GiST 인덱스보다 검색 속도가 빠르지 만 빌드 또는 업데이트 속도가 느립니다. 따라서 GIN은 정적 데이터에 더 적합하고 GiST는 자주 업데이트되는 데이터에 더 적합합니다.

그러나 거리 연산자를 사용하는 "가장 가까운 이웃"유형의 쿼리의 경우 <->:

이것은 GiST 인덱스가 아닌 GiST 인덱스에 의해 매우 효율적으로 구현 될 수 있습니다.


3
이것을 읽으면서 GIN을 사용할지 GiST를 사용할지 궁금했습니다. 내가 읽은 내용에 따르면 GIN 색인은 유지 관리 비용이 많이 들지만 검색 속도가 빠르며 GiST 색인은 유지 관리 비용이 저렴하지만 검색 속도가 느립니다. 즉, GIN 인덱스는 일반적으로 상대적으로 정적 인 데이터에 사용해야하며 GiST 인덱스는 더 많이 변경되는 테이블에 선호됩니다.
Colin 't Hart

1
@ Colin'tHart : 일반적으로 사실이지만 규칙에는 예외가 있습니다. 위의 부록을 고려하십시오.
Erwin Brandstetter

5

MySQL에 대해 말하면 와일드 카드 문자 (%)의 위치가 달라집니다. 텍스트의 첫 번째 부분 where first_name like 'Sta%'이처럼 지정 되면 DB 엔진은 S로 시작하고 St로 이동 한 다음 Sta로 이동하는 단어의 작은 하위 집합 만 검색 where first_name like '%stan%'합니다. 열이 필요합니다. 또한 자연어 검색을 수행하는 전체 텍스트 인덱스를 살펴볼 수도 있습니다. 여기에서 MySQL 문서를 확인하십시오.


1
하위 문자열이 3 자로 정의 될 때 왜 "S %"검색을 시작합니까 (예 : 문자열이 "Sr %"가 아님)? 또는 DB에 속성에 접두사 트리가 있다고 가정 하고이 트리를 통과하는 예를 제공합니까?
Nick
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.