2011-02-14 5 views
0

다음은 "amadeus"하위 문자열을 검색 할 때 얻을 수있는 데이터의 예입니다.Postgresql 색인 생성 소문자 (열)가 예상대로 작동하지 않습니까?

db=# SELECT entidade FROM gma WHERE entidade ILIKE '%amadeus%'; 
      entidade 
--------------------------------- 
Hairdresser Amadeus 
Snack-Bar Amadeus 
Restaurant Amadeus 
Restaurant Amadeus 
Restaurant Amadeus 
Amadeus - Musical Instruments 
(6 rows) 

그러나 LIKEILIKE로 대체 할 수 있기를 원합니다. 그래서 저는 소문자로만 entidade을 색인하려고했습니다 :

db=# CREATE INDEX idx_gma_entidade ON gma USING btree 
db-# (lower(entidade)); 
CREATE INDEX 

지금까지는 LIKE을 사용하여 정확히 동일한 데이터에 액세스하려고합니다 :

db=# SELECT entidade FROM gma WHERE entidade LIKE '%amadeus%'; 
entidade 
---------- 
(0 rows) 

그러나 알 수 있듯이 결과는 내가 예상했던 것이 아니야 ... 누군가가 왜 그 이유를 설명 할 수 있니? 그리고 가능한 한 어떻게 예상 된 행동을 성취 할 수 있습니까?

답변

2

당신은 당신의 선택을 실행할 때 열을 낮은() 함수를 사용해야합니다. 그래서 을 구현 만하는 방법, 쿼리의결과를 변경해서는 안 인덱스를 생성 한

+0

감사합니다. a_horse_with_no_name ...하지만 인덱스를 만들 때 표현식을 허용하는 점에 대해 설명해 주시겠습니까? 그 표현은 어떻게 사용됩니까? 만약 내가 'SELECT entidade FROM gma where entidade LIKE'amadeus % '를 실행하면 소문자 인덱스가 사용됩니까? – acm

+0

@Andre : 인덱싱 된 표현식이 쿼리의 일부가 아니기 때문에 그렇지 않습니다. 'SELECT entidade FROM gma WHERE lower (entidade) LIKE'amadeus % ';'명령문은 인덱스를 사용합니다. –

2

btree 인덱스를 사용할 수 없습니다. 검색 문자열의 시작 부분에 와일드 카드를 사용하면 색인이 쓸모 없게됩니다.

전체 텍스트 검색을 사용하거나 wildspeed을 살펴보십시오.

SELECT entidade FROM gma WHERE lower(entidade) LIKE '%amadeus%';

을하지만 전면에 와일드 카드를 가지고 있기 때문에, 쿼리 어쨌든 인덱스를 사용하지 않습니다 :

1

를 만드는 아무 소용이 없다. 텍스트 열에 대해 대소 문자를 구분하지 않으려면 ILIKE 또는 lower(column) LIKE '...'과 같은 구조를 지정해야합니다. citext contrib 모듈을 사용하여 원하는대로 보이는 대소 문자를 구분하지 않는 citext 유형을 만들 수 있습니다.

관련 문제