나는 테이블은 사용자에게 열 개 제목의 목록을 보여주는, 내가 검색 필드의 자동 완성을 위해 해당 테이블의 정보를 사용하려면프리픽스 검색을 위해 PostgreSQL DB를 최적화하는 방법은 무엇입니까?
=#\d nodes
Table "public.nodes"
Column | Type | Modifiers
--------+------------------------+-----------
id | integer | not null
title | character varying(256) |
score | double precision |
Indexes:
"nodes_pkey" PRIMARY KEY, btree (id)
내 PostgreSQL의 DB에 약 170 만 행이 "노드"라고했다 자신의 의견에 가장 적합한 점수를 얻습니다. 그래서이 쿼리를 사용했습니다. 여기에서 "s"로 시작하는 모든 제목을 검색합니다.
=# explain analyze select title,score from nodes where title ilike 's%' order by score desc;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Sort (cost=64177.92..64581.38 rows=161385 width=25) (actual time=4930.334..5047.321 rows=161264 loops=1)
Sort Key: score
Sort Method: external merge Disk: 5712kB
-> Seq Scan on nodes (cost=0.00..46630.50 rows=161385 width=25) (actual time=0.611..4464.413 rows=161264 loops=1)
Filter: ((title)::text ~~* 's%'::text)
Total runtime: 5260.791 ms
(6 rows)
이것은 자동 완성과 함께 사용하는 것이 훨씬 느립니다. Using PostgreSQL in Web 2.0 Applications에서 몇 가지 정보를 통해 내가 그래서이 더욱 향상 될 수 내게 요인 그러나 4의 속도 향상을 준 특별한 인덱스
=# create index title_idx on nodes using btree(lower(title) text_pattern_ops);
=# explain analyze select title,score from nodes where lower(title) like lower('s%') order by score desc limit 10;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=18122.41..18122.43 rows=10 width=25) (actual time=1324.703..1324.708 rows=10 loops=1)
-> Sort (cost=18122.41..18144.60 rows=8876 width=25) (actual time=1324.700..1324.702 rows=10 loops=1)
Sort Key: score
Sort Method: top-N heapsort Memory: 17kB
-> Bitmap Heap Scan on nodes (cost=243.53..17930.60 rows=8876 width=25) (actual time=96.124..1227.203 rows=161264 loops=1)
Filter: (lower((title)::text) ~~ 's%'::text)
-> Bitmap Index Scan on title_idx (cost=0.00..241.31 rows=8876 width=0) (actual time=90.059..90.059 rows=161264 loops=1)
Index Cond: ((lower((title)::text) ~>=~ 's'::text) AND (lower((title)::text) ~<~ 't'::text))
Total runtime: 1325.085 ms
(9 rows)
와 그 개선 할 수 있었다? 's%'
대신 '%s%'
을 사용하려면 어떻게해야합니까? 이 경우에도 PostgreSQL과 함께 훌륭한 성능을 얻을 수있는 기회가 있습니까? 또는 내 자동 완성 기능을 구현하기 위해 다른 솔루션 (Lucene?, Sphinx?)을 사용해 보는 것이 좋습니다. 추가 조사를 위해