POSTgres에서 LIKE와 ~의 차이
"당신을 귀찮게 하지 말라"는 지시를 받았어요.LIKE
및사를 합니다.~
대신.무슨 문제가 있습니까?LIKE
그리고 어떻게 지내십니까?~
른가요다?
있습니까?~
이런 맥락에서 이름을 가지고 있거나 사람들이 "틸드 연산자를 사용한다"고 말합니까?
~
는 정규식 연산자이며, 이에 의해 암시되는 기능을 가지고 있습니다.정규식 와일드카드 및 한정자의 전체 범위를 지정할 수 있습니다. 자세한 내용은 설명서를 참조하십시오.그것은 확실히 더 강력합니다.LIKE
그리고 그 힘이 필요할 때 사용되어야 하지만, 그들은 다른 목적을 위해 사용됩니다.
에 아무런 문제가 없습니다.LIKE
그고리 IMO, ▁to▁favour▁reason다▁and.~
그 위에오히려 그 반대입니다.LIKE
SQL 표준입니다.그렇습니다. 하지만 널리 지원되지는 않습니다.포스트그레SQL(또는 posix 정규식 일치 연산자)은 SQL 표준이 아닙니다.
그런 이유로, 저는 사용하는 것을 선호합니다.LIKE
▁use곳▁it▁▁only하용▁i▁and내가ive'▁enough오직s.~
표현힘필이때요할의규한▁▁it때할요▁databases필▁i. 데이터베이스를 포팅해야 하는 라도 덜 데이터베이스를 포팅해야 하는 경우 하나라도 덜 아플 수 있습니다.제가 사용하는 경향이 있습니다.SIMILAR TO
때에LIKE
충분히 강력하지는 않지만, 어윈의 의견 이후에 저는 그것을 그만 하고 사용할 것 같습니다.~
때에LIKE
그 일을 하지 않습니다.
, Postgre.할 수 예: SQL 접 검 예 b-tree 인 스 할 있 습 니 수 다 용 사 를 덱 은 :LIKE 'TEST%'
)와 함께LIKE
또는SIMILAR TO
가 이터베에있경에 있는 C
에 " " "가 있습니다.text_pattern_ops
앞에서 쓴 것과 달리 Pg는 왼쪽 고정된 포식스 정규식에 이러한 인덱스를 사용할 수도 있습니다. 명시적인 '^TEST'만 있으면 됩니다.정규식은 처음부터 일치해야 합니다.아까 제 게시물에는 다음과 같이 잘못 기재되어 있습니다.~
접두사 검색에 인덱스를 사용할 수 없습니다.이러한 차이가 사라지면 가능한 한 표준 호환 기능을 고수할지 여부에 따라 결정됩니다.
이 데모 SQLFidle을 참조하십시오. 다양한 실행 계획을 확인하십시오.사이의 차이에 주목합니다.~ '1234.*'
그리고.~ '^1234.*'
.
주어진 표본 데이터:
create table test (
blah text
);
insert into test (blah) select x::text from generate_series(1,10000) x;
create index test_blah_txtpat_idx ON test(blah text_pattern_ops);
을 주의하여 보다~
비싼 합니다(구체적으로 seqscan 입니다).enable_seqscan
에, 에 )는 대안이 없습니다.LIKE
인덱스를 사용합니다.그나, 수됨은~
왼쪽 앵커의 경우 인덱스도 사용합니다.
regress=# SET enable_seqscan = 'f';
SET
regress=# explain select 1 from test where blah ~ '12.*';
QUERY PLAN
---------------------------------------------------------------------------
Seq Scan on test (cost=10000000000.00..10000000118.69 rows=2122 width=0)
Filter: (blah ~ '12.*'::text)
(2 rows)
regress=# explain select 1 from test where blah like '12%';
QUERY PLAN
------------------------------------------------------------------------------------
Bitmap Heap Scan on test (cost=4.55..46.76 rows=29 width=0)
Filter: (blah ~~ '12%'::text)
-> Bitmap Index Scan on test_blah_txtpat_idx (cost=0.00..4.54 rows=29 width=0)
Index Cond: ((blah ~>=~ '12'::text) AND (blah ~<~ '13'::text))
(4 rows)
regress=# explain select 1 from test where blah ~ '^12.*';
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on test (cost=5.28..51.53 rows=101 width=0)
Filter: (blah ~ '^12.*'::text)
-> Bitmap Index Scan on test_blah_txtpat_idx (cost=0.00..5.25 rows=100 width=0)
Index Cond: ((blah ~>=~ '12'::text) AND (blah ~<~ '13'::text))
(4 rows)
개요
LIKE
,SIMILAR TO
그리고.~
Postgre의 기본 패턴 매칭 연산자입니다.SQL.
가능하면 ()를 ~~
사용하는 것이 가장 빠르고 간단합니다.
그럴 수 없는 경우 정규 ~
표현()을 사용하면 더 강력합니다.
사용자 없음
SIMILAR TO
무의미합니다.아래를 참조하십시오.
추가 모듈 pg_trgm을 설치하면 고급 인덱스 옵션과 유사성 연산자가 추가됩니다.
그리고 자체 인프라와 운영자(다른 것들 중)를 사용한 텍스트 검색도 있습니다.
인덱스 지원은 각 연산자에 대해 다양한 수준으로 제공됩니다.정기적으로 다른 옵션의 성능을 능가합니다.하지만 세부적인 부분에는 많은 여유가 있습니다. 심지어 지수도 마찬가지입니다.
인덱스 지원
pg_trgm을 사용하지 않으면 왼쪽 고정 검색 패턴에 대한 인덱스만 지원됩니다.데이터베이스 클러스터가 C가 아닌 로케일(일반적인 경우)로 실행되는 경우 다음과 같은 특수 연산자 클래스가 있는 인덱스가 필요합니다.text_pattern_ops
또는varchar_pattern_ops
기본적인 왼쪽 고정 정규식도 이에 의해 지원됩니다.예:
CREATE TABLE tbl(string text);
INSERT INTO tbl(string)
SELECT x::text FROM generate_series(1, 10000) x;
CREATE INDEX tbl_string_text_pattern_idx ON tbl(string text_pattern_ops);
SELECT * FROM tbl WHERE string ~ '^1234'; -- left anchored pattern
db<>여기로 이동
pg_trgm을 설치하면 연산자 클래스에서 GIN 또는 GiST 인덱스를 사용할 수 있습니다.gist_trgm_ops
또는gin_trgm_ops
이 인덱스는 다음 항목을 지원합니다. LIKE
그냥 고정된 상태로 두는 것이 아니라 표현.설명서를 인용하여 설명합니다.
Postgre에서 시작SQL 9.3에서 이러한 인덱스 유형은 정규식과 일치하는 인덱스 검색도 지원합니다.
세부사항:
SIMILAR TO
매우 이상한 구조입니다.포스트그레SQL 표준의 초기 버전에서 정의되었기 때문에 SQL에서만 이를 구현합니다.내부적으로, 모든SIMILAR TO
식을 정규식으로 다시 씁니다.그러므로, 어떤 주어진 경우에도.SIMILAR TO
식, 동일한 작업을 더 빨리 수행하는 정규식이 하나 이상 있습니다.절대 사용 안 함SIMILAR TO
.
자세한 내용:
좋아요는 시작이나 끝 또는 중간 문자열의 일부와 일치합니다. 기울기(~)는 정규식과 일치합니다.
이를 더 설명하기 위해 표를 만들고 몇 가지 값을 삽입합니다.
# create table users(id serial primary key, name character varying);
이제 표에 몇 가지 값을 삽입하겠습니다.
# insert into users (name) VALUES ('Alex'), ('Jon Snow'), ('Christopher'), ('Arya'),('Sandip Debnath'), ('Lakshmi'),('alex@gmail.com'),('@sandip5004'), ('lakshmi@gmail.com');
이제 당신의 테이블은 이 모양이어야 합니다.
id | name
----+-------------------
1 | Alex
2 | Jon Snow
3 | Christopher
4 | Arya
5 | Sandip Debnath
6 | Lakshmi
7 | alex@gmail.com
8 | lakshmi@gmail.com
9 | @sandip5004
케이스 LIKE
# select * from users where name like 'A%';
id | name
----+------
1 | Alex
4 | Arya
(2 rows)
당신이 볼 수 있듯이.'A%'
이름이 대문자 A로 시작하는 값만 얻을 수 있습니다.
# select * from users where name like '%a%';
id | name
----+-------------------
4 | Arya
5 | Sandip Debnath
6 | Lakshmi
7 | alex@gmail.com
8 | lakshmi@gmail.com
당신이 볼 수 있듯이.'%a%'
이름이 다음과 같은 값만 얻을 수 있습니다.a
이름 사이에
# select * from users where name like '%a';
id | name
----+------
4 | Arya
당신이 볼 수 있듯이.'%a'
이름이 다음으로 끝나는 값만 얻을 수 있습니다.a
.
대소문자 - (기울임)
# select * from users where name ~* 't';
id | name
----+----------------
3 | Christopher
5 | Sandip Debnath
당신이 볼 수 있듯이.name ~* 't'
이름이 다음과 같은 값만 얻을 수 있습니다.t
.~
대소문자 구분을 의미하고 ~*는 대소문자 구분을 의미하므로
# select * from users where name ~ 'T';
id | name
----+------
(0 rows)
위의 쿼리는 우리에게 0개의 행을 주었습니다.T
어떤 항목과도 일치하지 않았습니다.
이제 이메일 ID만 가져오면 되고 메일 ID에 무엇이 있는지 알 수 없지만 이메일 패턴을 알고 있는 경우를 생각해 보겠습니다. 즉, 문자나 숫자 또는 _ 또는 . 또는 -, @, 그 다음에는 더 많은 문자나 숫자 또는 -가 있을 것입니다.com
또는in
또는org
etc
정규 표현을 사용하여 패턴을 만들 수 있습니다.
이제 정규식을 사용하여 결과를 가져오도록 하겠습니다.
# select * from users where name ~* '[a-z0-9\.\-\_]+@[a-z0-9\-]+\.[a-z]{2,5}';
id | name
----+-------------------
7 | alex@gmail.com
8 | lakshmi@gmail.com
마찬가지로 우리는 사이에 공백이 있는 이름을 가져올 수 있습니다.
#select * from users where name ~* '[a-z]+\s[a-z]+';
id | name
----+----------------
2 | Jon Snow
5 | Sandip Debnath
[a-z]+는 a에서 z까지의 문자가 있을 수 있음을 의미하고 +는 1회 이상 발생할 수 있음을 의미하며 \s는 그 사이에 공백이 있다가 다시 1회 이상 발생할 수 있음을 의미합니다.
이 상세한 분석이 도움이 되길 바랍니다.
그~~
연산자는 다음과 같습니다.LIKE
. ~
반면에 POSIX 정규식을 사용하여 일치합니다.
인덱스가 포함되지 않은 경우 두 운영자 간의 성능 차이를 살펴보기 위해 빠르고 간단한 벤치마크를 수행했습니다.
postgres=# \timing
Timing is on.
postgres=# SELECT count(1) FROM (SELECT val from generate_series(1, 10000000) x(val) WHERE val::text LIKE '%5%') AS x;
count
─────────
5217031
(1 row)
Time: 5631.662 ms
postgres=# SELECT count(1) FROM (SELECT val from generate_series(1, 10000000) x(val) WHERE val::text ~ '5') AS x;
count
─────────
5217031
(1 row)
Time: 10612.406 ms
이 예에서는LIKE
연산자는 거의 두 배 더 빠릅니다.~
교환입니다.그래서 속도가 중요하다면 저는 그 쪽으로 기울 것입니다.LIKE
하지만 너무 일찍 최적화하지 않도록 주의해야 합니다. ~
유연성이 훨씬 높아집니다.
관심 있으신 분들을 위해, 여기 있습니다.EXPLAIN
쿼리에 : " " " 은 다음과 같습니다.
postgres=# EXPLAIN ANALYZE SELECT count(1) FROM (SELECT val from generate_series(1, 10000000) x(val) WHERE val::text LIKE '%5%') AS x;
QUERY PLAN
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Aggregate (cost=20.00..20.01 rows=1 width=0) (actual time=9967.748..9967.749 rows=1 loops=1)
-> Function Scan on generate_series x (cost=0.00..17.50 rows=1000 width=0) (actual time=1732.084..7404.755 rows=5217031 loops=1)
Filter: ((val)::text ~~ '%5%'::text)
Rows Removed by Filter: 4782969
Total runtime: 9997.587 ms
(5 rows)
postgres=# EXPLAIN ANALYZE SELECT count(1) FROM (SELECT val from generate_series(1, 10000000) x(val) WHERE val::text ~ '5') AS x;
QUERY PLAN
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Aggregate (cost=20.00..20.01 rows=1 width=0) (actual time=15118.061..15118.061 rows=1 loops=1)
-> Function Scan on generate_series x (cost=0.00..17.50 rows=1000 width=0) (actual time=1724.591..12516.996 rows=5217031 loops=1)
Filter: ((val)::text ~ '5'::text)
Rows Removed by Filter: 4782969
Total runtime: 15147.950 ms
(5 rows)
네, POSIX regex의 약자입니다.또 다른 대안은 정규식에 대한 SQL 표준 접근 방식을 "유사한 대상" 연산자와 함께 사용하는 것입니다. 더 제한된 기능 집합을 제공하지만 이해하기가 더 쉬울 수 있습니다.저는 이것이 dba exchange의 좋은 참고 자료라고 생각합니다. https://dba.stackexchange.com/questions/10694/pattern-matching-with-like-similar-to-or-regular-expressions-in-postgresql
언급URL : https://stackoverflow.com/questions/12452395/difference-between-like-and-in-postgres
'programing' 카테고리의 다른 글
Int, Int16, Int32 및 Int64의 차이점은 무엇입니까? (0) | 2023.05.15 |
---|---|
파이썬 3에서 stdout에 이진 데이터를 쓰는 방법은 무엇입니까? (0) | 2023.05.15 |
일부 컨텍스트를 전달하는 동안 expressjs에서 리디렉션하려면 어떻게 해야 합니까? (0) | 2023.05.15 |
마지막으로 삽입한 ID에 대한 PostgreSQL 함수 (0) | 2023.05.15 |
작업을 취소하려면 어떻게 해야 합니까?언제 다? (0) | 2023.05.15 |