여러 열로 Postgres 전체 텍스트 검색, 왜 런타임이 아닌 인덱스로 연결합니까?


11

지난 며칠 동안 postgres에서 전체 텍스트 검색을 보았으며 여러 열을 검색 할 때 색인 작성에 대해 약간 혼란 스럽습니다.

postgres 문서ts_vector 는 다음과 같이 연결된 열에 인덱스를 만드는 것에 대해 이야기합니다 .

CREATE INDEX pgweb_idx ON pgweb 
    USING gin(to_tsvector('english', title || ' ' || body));

내가 그렇게 검색 할 수 있습니다 :

... WHERE 
      (to_tsvector('english', title||' '||body) @@ to_tsquery('english', 'foo'))

그러나 제목, 때로는 본문 및 때로는 둘 다 검색하려는 경우 3 개의 별도 색인이 필요합니다. 세 번째 열에 추가하면 잠재적으로 6 개의 인덱스 등이 될 수 있습니다.

문서에서 보지 못한 대안은 두 열을 별도로 색인화 한 다음 일반 WHERE...OR쿼리를 사용하는 것입니다 .

... WHERE
      (to_tsvector('english', title) @@ to_tsquery('english','foo'))
    OR
      (to_tsvector('english', body) @@ to_tsquery('english','foo'))

~ 1 백만 행에 두 개를 벤치마킹하면 기본적으로 성능에 차이가없는 것 같습니다.

그래서 내 질문은 :

열을 개별적으로 인덱싱하지 않고 이와 같은 인덱스를 연결하려는 이유는 무엇입니까? 두 가지의 장단점은 무엇입니까?

가장 좋은 추측은 사전에 알고 있다면 두 열 (한 번에 한 번만)을 검색하지 않고 메모리를 덜 사용하는 하나의 색인 만 연결하면된다는 것입니다.


을 연결하는 방법을 정말 확실하지 않다 titlebody내가 수정 문을 열어주는 말들하지만 다음, 그 많은 가치를 줄 것이다 색인. 아마 그것들을 따로 인덱싱하는 것을 고수했을 것입니다. 또한 어쨌든 연결 해야하는 엉뚱한 일회성 인 경우 쿼리를 임시로 실행할 수 있다고 생각합니다.
swasheck

당신은 당신의 추측에 맞습니다. 다른 사람이 없다면 스스로 대답 해 보시기 바랍니다.
jcolebrand

답변:


4

아니요 별도의 색인이 필요하지 않습니다. 가중치 기능을 사용하십시오. 그들은 당신이 쿼리 할 수있는 레이블 일뿐입니다. (AD)에 대해 쿼리 할 레이블을 최대 4 개까지 가질 수 있습니다.

--search any "field" for quick:
select 'quick:1A brown:2B quick:3C'::tsvector @@ 'quick'::tsquery; --true

--search B "field" for quick:
select 'quick:1A brown:2B quick:3C'::tsvector @@ 'quick:B'::tsquery; --false

--search B or C "fields" for quick:
select 'quick:1A brown:2B quick:3C'::tsvector @@ 'quick:BC'::tsquery; --true

tsvectors를 연결하여 가중치를 별도로 적용한 다음 하나로 묶을 수 있습니다.

select
  setweight( name_column::tsvector, 'A') || setweight( phone_column::tsvector, 'B');

3

실제로 대안은 AND가 아닌 OR로 where를 사용하는 것입니다 .

tsvector (body + title)에 대한 색인이 있고 검색하는 경우 검색된 단어의 제목 또는 본문이 될 수 있습니다 .

또한 테스트 할 때 테이블에 적절한 수의 행이 있는지 확인하십시오.

좋은 차이를 보여줄 수있는 가장 간단한 경우 : 두 단어를 찾으십시오. 그 중 하나는 제목에있을 가능성이 높습니다. 다른 하나는 몸에있을 가능성이 높습니다. 그러나 기준 과 일치 하는 행이 많지 않아야 합니다. 예를 들어, 단어 "depesz"의 30 %가 본문에있을 수 있습니다. 제목이 "mysql"일 가능성이 ~ 30 %입니다. 그러나 같은 행의 필드에 "depesz 및 mysql"이있는 경우는 거의 없습니다. 그런 다음 해당 색인으로 성능을 확인하십시오.


하, 좋은 자리, OR 대 그리고 나는 질문을 업데이트 할 것입니다. 나는 1Million 행으로 그것을했다-더 이상 삽입을 기다릴 귀찮게 :)
latentflip

1
나는 당신이 주변 :-) 스틱 바랍니다 않도록 우리가 요즘 꽤 많은 포스트 그레스 질문을 받고 - depesz 들러 주셔서 감사합니다
잭은 말한다 topanswers.xyz 시도

@ 잭 : 확실하지 않습니다-stackexchange 사이트의 사용이 점점 줄어 들었습니다. 나는 일반적으로 RSS를 얻으려고 노력하지만 stackexchange 사이트에서 rss는 거의 쓸모가 없습니다. 오래된 질문의 판에서 너무 많은 오염.

내가 당신을 위해 RSS 피드를 만들었습니다 여기에 - 당신은 시도 것을 포기할 수 있습니까? 난 당신이 더 :-) 사이트에 관여 한 수있는 기회를 얻을에 관심이있을 가능성이있는 물건을 필터링의 노력을 행복 해요
잭 topanswers.xyz 시도라고

잭 :) 물지-구독.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.