SQL 인덱스를 사용하면 내 쿼리와 일치하는 문자열을 빠르게 찾을 수 있습니다. 이제 큰 테이블에서 이 아닌 문자열을 검색해야합니다.이 일치해야합니다. 물론, 일반 인덱스는 도움이되지 않습니다와 나는 느린 순차 검색 할 필요가 :"같지 않음"검색에 대한 SQL 인덱스
essais=> \d phone_idx
Index "public.phone_idx"
Column | Type
--------+------
phone | text
btree, for table "public.phonespersons"
essais=> EXPLAIN SELECT person FROM PhonesPersons WHERE phone = '+33 1234567';
QUERY PLAN
-------------------------------------------------------------------------------
Index Scan using phone_idx on phonespersons (cost=0.00..8.41 rows=1 width=4)
Index Cond: (phone = '+33 1234567'::text)
(2 rows)
essais=> EXPLAIN SELECT person FROM PhonesPersons WHERE phone != '+33 1234567';
QUERY PLAN
----------------------------------------------------------------------
Seq Scan on phonespersons (cost=0.00..18621.00 rows=999999 width=4)
Filter: (phone <> '+33 1234567'::text)
(2 rows)
을 이해 (마크 바이어스 '아주 좋은 설명을 참조)이 볼 때 PostgreSQL을 는 인덱스를 사용하지 않기로 결정할 수 순차 주사 이 더 빠를 것입니다 (예를 들어 거의 모든 튜플이 일치하는 경우). 그러나 여기에서 "같지 않음"검색은 실제로 느립니다.
"이와 동등하지 않습니다"검색을 더 빨리 수행 할 수있는 방법은 무엇입니까?
마크 바이어스 (Mark Byers)의 훌륭한 발언을 다루기위한 또 다른 예가 있습니다. 지수 ( 튜플의 대부분을 반환)가 '='쿼리에 사용하지만 쿼리됩니다 '! ='
essais=> \d tld_idx
Index "public.tld_idx"
Column | Type
-----------------+------
pg_expression_1 | text
btree, for table "public.emailspersons"
essais=> EXPLAIN ANALYZE SELECT person FROM EmailsPersons WHERE tld(email) = 'fr';
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------
Index Scan using tld_idx on emailspersons (cost=0.25..4010.79 rows=97033 width=4) (actual time=0.137..261.123 rows=97110 loops=1)
Index Cond: (tld(email) = 'fr'::text)
Total runtime: 444.800 ms
(3 rows)
essais=> EXPLAIN ANALYZE SELECT person FROM EmailsPersons WHERE tld(email) != 'fr';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Seq Scan on emailspersons (cost=0.00..27129.00 rows=2967 width=4) (actual time=1.004..1031.224 rows=2890 loops=1)
Filter: (tld(email) <> 'fr'::text)
Total runtime: 1037.278 ms
(3 rows)
는 DBMS는 PostgreSQL의 8.3입니다 (하지만 8.4으로 업그레이드 할 수 있습니다) .
"<>"을 (를) "< OR >"(으)로 다시 작성하는 아이디어를 테스트 한 결과 작동했습니다. EXPLAIN은 인덱스가 사용되고 성능이 많이 향상됨을 보여줍니다. 나는 더 많은 시험을하고 당신의 대답을 받아 들일 것입니다. 질문 : PostgreSQL이이 재 작성 자체를 할 수없는 이유는 무엇입니까? – bortzmeyer
@bortzmeyer 아마도 운영자 시스템이 너무 일반적이기 때문에 "="/ "<>"쌍의 연산자를 "<" and ">"과 연관시키는 방법이 필요합니다. PostgreSQL 목록에 기능으로 제안하는 것이 좋습니다. – araqnid
OK, 괜찮습니다. 감사합니다. 작은 경고 : 모든 PostgreSQL 인덱스가 순서를 가지고 있지는 않습니다. http://www.postgresql.org/docs/current/interactive/indexes-types.html – bortzmeyer