2013-06-04 94 views
1

我在RHEL 5.8 OS上运行postgresql-9.1.6。我得到了一个声明执行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) 

不知什么是WHY ???

+0

请向我们展示您希望查询使用的索引的定义。 –

+0

对不起,表格描述被遗漏了... – KIM

回答

3

避免使用char数据类型。很多原因都很糟糕,而且这只是其中之一。

如果你坚持textvarchar你会有更少的问题与隐式强制转换和混淆行为。

+0

有没有我可以获得关于char类型问题的更多信息的任何引用? – KIM

+0

@KIM手册:http://www.postgresql.org/docs/current/static/datatype-character.html –

4

从第一个计划看来,在col1上执行隐式类型转换以匹配right()的返回类型。

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

很明显,表达式权利('10000081',3)返回文本。

所以我会说,是的,你必须键入表达式,虽然替代方法将索引(col1)::文本 - 不是我最喜欢的解决方案。

+0

如果是这样,那就意味着WAR! – KIM