【发布时间】:2011-02-21 07:09:30
【问题描述】:
SQL 索引允许快速找到与我的查询匹配的字符串。现在,我必须在一个大表中搜索 not 匹配的字符串。当然,普通的索引也无济于事,我必须进行慢速顺序扫描:
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)
我理解(参见 Mark Byers 的非常好的解释)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)。
【问题讨论】:
标签: sql postgresql indexing