2013-06-04 4 views
1

Я запускаю postgresql-9.1.6 на RHEL 5.8 OS. Я получил заявление, в котором выполняется seq-сканирование, по которому индексируется столбец.Почему мой индекс не используется

      Table "public.table" 
Column |   Type   |    Modifiers     
----------+-----------------------+----------------------------------------- 
col1  | character(3)   | not null 
col2  | character varying(20) | not null 
col3  | character varying(20) | 
col4  | character(1)   | default 0 
Indexes: 
    "table_pkey" PRIMARY KEY, btree (col1, col2) 


postgres=# explain analyze select * from table where col1=right('10000081',3); 
                 QUERY PLAN              
---------------------------------------------------------------------------------------------------------------------- 
Seq Scan on table (cost=0.00..31053.24 rows=5650 width=286) (actual time=3.221..429.950 rows=110008 loops=1) 
    Filter: ((col1)::text = '081'::text) 
Total runtime: 435.904 ms 
(3 rows) 

postgres=# explain analyze select * from table where col1=right('10000081',3)::char(3); 
                   QUERY PLAN                 
----------------------------------------------------------------------------------------------------------------------------------------- 
Bitmap Heap Scan on table (cost=3097.81..18602.98 rows=112173 width=286) (actual time=18.125..32.707 rows=110008 loops=1) 
    Recheck Cond: (col1 = '081'::character(3)) 
    -> Bitmap Index Scan on table_pkey (cost=0.00..3069.77 rows=112173 width=0) (actual time=17.846..17.846 rows=110008 loops=1) 
     Index Cond: (col1 = '081'::character(3)) 
Total runtime: 38.640 ms 
(5 rows) 

и я обнаружил, что [изменить столбец] является одним из раствора ....

postgres=# alter table table alter column col1 type varchar(3);    
ALTER TABLE 
postgres=# explain analyze select * from table where col1=right('10000081',3); 
                   QUERY PLAN                
-------------------------------------------------------------------------------------------------------------------------------------- 
Bitmap Heap Scan on table (cost=160.26..10902.32 rows=5650 width=295) (actual time=20.249..41.658 rows=110008 loops=1) 
    Recheck Cond: ((col1)::text = '081'::text) 
    -> Bitmap Index Scan on table_pkey (cost=0.00..158.85 rows=5650 width=0) (actual time=20.007..20.007 rows=110008 loops=1) 
     Index Cond: ((col1)::text = '081'::text) 
Total runtime: 47.408 ms 
(5 rows) 

Что мне интересно, ПОЧЕМУ ???

+0

Пожалуйста, покажите нам определение индекса, который вы ожидаете использовать. –

+0

извините, описание таблицы было пропущено ... – KIM

ответ

3

Избегайте использования char. Это ужасно по многим причинам, и это только один из них.

Если вы придерживаетесь text или varchar, у вас будет меньше проблем с неявным отбрасыванием и запутанным поведением.

+0

Есть ли какая-либо ссылка, которую я могу получить больше информации о проблеме типа char? – KIM

+0

@KIM Руководство: http://www.postgresql.org/docs/current/static/datatype-character.html –

4

С первого плана видно, что при сопоставлении типа возврата right() выполняется неявное преобразование типов, выполняемое на col1.

Filter: ((col1)::text = '081'::text) 

Очевидно, что выражение right ('10000081', 3) возвращает текст.

Поэтому я бы сказал, что да, вам нужно набирать текст, хотя альтернативой было бы индексировать (col1) :: text - не мое любимое решение.

+0

Если это так, значит WAR! – KIM

Смежные вопросы