콘텐츠로 건너뛰기
리뷰나라
  • JAVASCRIPT
  • JAVA
  • PYTHON
  • C#
  • Android
  • Html

[postgresql] PostgreSQL LIKE 쿼리 성능 변화

Program / 글쓴이 어드민

LIKE내 데이터베이스의 특정 테이블에 대한 쿼리 와 관련하여 응답 시간이 상당히 많이 변하는 것을 보았습니다 . 때로는 200-400ms (매우 수용 가능) 내에 결과를 얻을 수 있지만 결과를 반환하는 데 30 초 정도 걸릴 수도 있습니다.

LIKE쿼리가 매우 리소스 집약적 이라는 것을 이해 하지만 응답 시간에 그렇게 큰 차이가있는 이유를 이해할 수 없습니다. owner1필드 에 btree 인덱스를 만들었지 만 LIKE쿼리에 도움이되지 않는다고 생각 합니다. 누구나 아이디어가 있습니까?

샘플 SQL :

SELECT gid, owner1 FORM parcels
WHERE owner1 ILIKE '%someones name%' LIMIT 10

나는 또한 시도했다 :

SELECT gid, owner1 FROM parcels
WHERE lower(owner1) LIKE lower('%someones name%') LIMIT 10

과:

SELECT gid, owner1 FROM parcels
WHERE lower(owner1) LIKE lower('someones name%') LIMIT 10

비슷한 결과가 있습니다.
테이블 행 수 : 약 95,000.



답변

FTS는 지원하지 않습니다 LIKE

이전에 허용 대답은 잘못되었습니다. 전체 텍스트 인덱스가있는 전체 텍스트 검색 은 연산자를 위한 것이 아닙니다.LIKE 자체 연산자가 있으며 임의의 문자열에 대해서는 작동하지 않습니다. 사전 및 형태소 분석을 기반으로 하는 단어로 작동합니다 . 그것은 않습니다 지원 단어에 대한 접두사 일치를 에 있지만 LIKE운영자 :

  • GIN 인덱싱 된 TSVECTOR 열에서 부분 일치 가져 오기

Trigram 인덱스 LIKE

GIN 및 GiST 트라이 그램 인덱스 에 pg_trgm대한 연산자 클래스를 제공 하는 추가 모듈 을 설치하여 왼쪽 앵커뿐만 아니라 모든 및 패턴 을 지원 합니다.LIKEILIKE

색인 예 :

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);
  • GiST와 GIN 지수의 차이점

쿼리 예 :

SELECT * FROM tbl WHERE col LIKE '%foo%';   -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%';  -- works case insensitively as well

트라이 그램? 짧은 문자열은 어떻습니까?

인덱싱 된 값 이 3 자 미만인 단어는 여전히 작동합니다. 매뉴얼 :

각 단어는 문자열에 포함 된 트라이 그램 집합을 결정할 때 접두사 2 개와 접미사 1 개 공백이있는 것으로 간주됩니다.

그리고 3 자 미만의 검색 패턴? 매뉴얼 :

LIKE정규식 검색과 정규식 검색 모두 에 대해 추출 가능한 트라이 그램이없는 패턴은 전체 인덱스 스캔으로 저하된다는 점에 유의하십시오.

즉, 인덱스 / 비트 맵 인덱스 스캔은 여전히 ​​작동하지만 (준비된 명령문에 대한 쿼리 계획은 중단되지 않음) 더 나은 성능을 얻을 수 없습니다. 일반적으로 1 자 또는 2 자 문자열은 선택성이 거의없고 (기본 테이블 일치의 몇 퍼센트 이상) 인덱스 지원으로 인해 전체 테이블 스캔이 더 빠르기 때문에 성능이 향상되지 않기 때문에 큰 손실이 없습니다.

text_pattern_ops 접두사 일치

단지를 들어 왼쪽 고정 된 패턴 당신은 적절한에 최적의 수 (더 와일드 카드를 선도 없음) 연산자 클래스 하십시오 BTREE 지수를 text_pattern_ops나 varchar_pattern_ops. 표준 Postgres의 두 내장 기능 모두 추가 모듈이 필요하지 않습니다. 성능은 비슷하지만 인덱스가 훨씬 작습니다.

색인 예 :

CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);

쿼리 예 :

SELECT * FROM tbl WHERE col LIKE 'foo%';  -- no leading wildcard

또는 ‘C’ 로케일로 데이터베이스를 실행해야하는 경우 (실제로 는 로케일 )로 어쨌든 모든 것이 바이트 순서에 따라 정렬되고 기본 연산자 클래스가있는 일반 btree 인덱스가 작업을 수행합니다.

dba.SE의 관련 답변에 대한 자세한 내용, 설명, 예제 및 링크 :

  • LIKE, SIMILAR TO 또는 PostgreSQL의 정규식을 사용한 패턴 일치
  • LIKE는 어떻게 구현됩니까?
  • PostgreSQL로 유사한 문자열을 빠르게 찾기

답변

아마도 빠른 것은 인덱스를 사용할 수있는 것과 같이 대소 문자를 구분하는 고정 된 패턴 일 것입니다. 즉, 일치 문자열의 시작 부분에 와일드 카드가 없으므로 실행 프로그램이 인덱스 범위 스캔을 사용할 수 있습니다. ( 문서의 관련 주석은 여기에 있습니다 ) Lower 및 ilike는 해당 목적을 위해 특별히 색인을 생성하지 않는 한 색인을 사용할 수있는 능력을 잃게됩니다 ( 기능 색인 참조 ).

필드 중간에있는 문자열을 검색하려면 전체 텍스트 또는 트라이 그램 인덱스를 살펴 봐야 합니다 . 첫 번째는 Postgres 코어에 있고 다른 하나는 contrib 모듈에서 사용할 수 있습니다.


답변

PostgreSQL에서 다른 유형의 인덱스 인 Wildspeed를 설치할 수 있습니다. Wildspeed는 % word % 와일드 카드와 함께 작동합니다. 문제 없습니다. 단점은 인덱스의 크기입니다. 이것은 매우 클 수 있습니다.


답변

postgresql에서 LIKE 쿼리 성능을 향상시키기 위해 아래 언급 된 쿼리를 실행하십시오. 더 큰 테이블에 대해 다음과 같은 색인을 작성하십시오.

CREATE INDEX <indexname> ON <tablename> USING btree (<fieldname> text_pattern_ops)


답변

그만한 가치 를 위해 Django ORM은 UPPER(text)모든 사람들 에게 사용하는 경향이 있습니다.LIKE 쿼리에 대소 문자를 구분하지 않는 .

색인을 추가하면 UPPER(column::text)다른 것과 달리 시스템 속도가 크게 빨라졌습니다.

선행 %까지는 인덱스를 사용하지 않습니다. 훌륭한 설명은이 블로그를 참조하십시오.

https://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning


답변

최근에 200000 개의 레코드가 포함 된 테이블에서 비슷한 문제가 발생하여 LIKE 쿼리를 반복해야합니다. 제 경우에는 검색중인 문자열이 수정되었습니다. 다른 분야는 다양했습니다. 그 때문에 다시 쓸 수있었습니다.

SELECT owner1 FROM parcels
WHERE lower(owner1) LIKE lower('%someones name%');

같이

CREATE INDEX ix_parcels ON parcels(position(lower('someones name') in lower(owner1)));

SELECT owner1 FROM parcels
WHERE position(lower('someones name') in lower(owner1)) > 0;

쿼리가 빠르게 돌아오고 인덱스가 EXPLAIN ANALYZE다음 과 함께 사용되는지 확인했을 때 기뻤습니다 .

 Bitmap Heap Scan on parcels  (cost=7.66..25.59 rows=453 width=32) (actual time=0.006..0.006 rows=0 loops=1)
   Recheck Cond: ("position"(lower(owner1), 'someones name'::text) > 0)
   ->  Bitmap Index Scan on ix_parcels  (cost=0.00..7.55 rows=453 width=0) (actual time=0.004..0.004 rows=0 loops=1)
         Index Cond: ("position"(lower(owner1), 'someones name'::text) > 0)
 Planning time: 0.075 ms
 Execution time: 0.025 ms


답변

유사한 쿼리는 다음과 같은 이유로 만든 색인을 사용할 수 없습니다.

1) LIKE 기준은 와일드 카드로 시작합니다.

2) LIKE 기준으로 함수를 사용했습니다.




글 탐색

← 이전 글
다음 글 →

최신 글

  • [java] .pem 파일을 읽고 개인 및 공개 키를 얻는 방법
  • [javascript] 페이지의 모든 AJAX 요청에 “후크”추가
  • [android] ListView가 접히지 않고 어떻게 ScrollView에 넣을 수 있습니까?
  • [linux] Apache 서버의 루트 디렉토리를 어떻게 변경합니까? [닫은]
  • [ios] Swift에서 Int를 Hex String으로 변환하는 방법
  • [python] 등급 시스템 기능에서 반복적 인 if-elif 문을 어떻게 단순화 할 수 있습니까?
  • [c#] C #에서 스택 오버플로 예외 포착
  • [windows] Windows의 /usr/local/ssl/openssl.cnf에서 구성 정보를로드 할 수 없습니다
  • [twitter-bootstrap] Bootstrap을 사용하여 모바일에 테이블을 표시하는 방법은 무엇입니까?
  • [windows] BATCH 스크립트에서 무작위로 사용하는 방법은 무엇입니까?

카테고리

태그

.net android angular angularjs arrays asp.net asp.net-mvc bash c c# css database django docker html ios iphone java javascript jquery json linux macos mysql node.js objective-c pandas php postgresql python r reactjs regex ruby ruby-on-rails shell sql sql-server string swift typescript unix visual-studio windows xcode
Copyright © daplus.net - Powered by Naya