我在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)
我发现[alter column]是解决方案之一......
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 :(得分:4)
从第一个计划看,在col1上执行了一个隐式类型转换,以匹配right()的返回类型。
Filter: ((col1)::text = '081'::text)
显然,表达式右('10000081',3)返回文本。
所以我会说是的,你必须输入表达式,尽管另一种方法是索引(col1):: text - 虽然不是我最喜欢的解决方案。
答案 1 :(得分:3)
避免使用char
数据类型。这有很多原因,这只是其中之一。
如果坚持使用text
或varchar
,那么隐式演员和混乱行为的问题会更少。