在postgreSQL 9.3.4中,我有一个由〜= 10百万个元素组成的表公司。我想检索第一个100K公司,naics
(字符变化)匹配前缀和顺序revenue
(Bigint)
此查询检索正确的结果(前缀为“11”):
SELECT c.* FROM Company c WHERE c.naics LIKE '11%' ORDER BY c.revenue DESC NULLS LAST LIMIT 100000
但我在运行时间方面存在一些问题
因此,我创建了3个索引:
- CREATE INDEX naics_pattern_text_revenue_limit_idx ON Company (naics text_pattern_ops, revenue DESC NULLS LAST)
- CREATE INDEX naics_pattern_text_idx ON Company (naics text_pattern_ops)
- CREATE INDEX naics_revenue_desc_idx ON Company (revenue DESC NULLS LAST)
但上一个查询不使用正确的索引:naics_pattern_text_revenue_limit_idx
但是naics_revenue_desc_idx
,并且不使用naics_revenue_desc_idx
上的索引 - >
EXPLAIN ANALYZE SELECT c.* FROM Company c WHERE c.naics LIKE '11%' ORDER BY revenue DESC NULLS LAST LIMIT 100000
Limit (cost=340805.34..341055.34 rows=100000 width=346) (actual time=1313.882..1358.690 rows=100000 loops=1)
-> Sort (cost=340805.34..341145.33 rows=135996 width=346) (actual time=1313.880..1349.020 rows=100000 loops=1)
Sort Key: revenue
Sort Method: external merge Disk: 44544kB
-> Bitmap Heap Scan on company c (cost=2855.63..285508.50 rows=135996 width=346) (actual time=42.681..1074.971 rows=167464 loops=1)
Filter: ((naics)::text ~~ '11%'::text)
Rows Removed by Filter: 2539459
-> Bitmap Index Scan on naics_pattern_text_idx (cost=0.00..2821.63 rows=134520 width=0) (actual time=41.289..41.289 rows=167464 loops=1)
Index Cond: (((naics)::text ~>=~ '11'::text) AND ((naics)::text ~<~ '12'::text))
Total runtime: 1417.166 ms
最烦人的部分是,如果我查询:
SELECT c.* FROM Company c WHERE c.naics LIKE '11%' LIMIT 100000
以567.184毫秒(使用naics_pattern_text_idx
)和
SELECT c.* FROM Company c ORDER BY revenue DESC NULLS LAST LIMIT 100000
以249.558毫秒运行(使用naics_revenue_desc_idx
)。
所以我的问题:
有没有办法在naics
和revenue
上创建postgreSQL正确考虑的索引?
我的印象是postgreSQL应该能够在公司的一个较小的子集上使用revenue
上的索引(一旦它被naics
过滤)。我错过了什么吗?
PS:我们(几乎)从不在公司表中插入新数据。我们只想优化select
update
和insert
的开销成本。