PostgreSQL:text\u pattern\u ops和Order by上的索引可以单独正常工作,但不在同一个SELECT中

PostgreSQL:text\u pattern\u ops和Order by上的索引可以单独正常工作,但不在同一个SELECT中,sql,postgresql,Sql,Postgresql,在postgreSQL 9.3.4中,我有一个由~=1000万个元素组成的表公司。我想检索第一个10万家公司,naics(字符变化)通过revenue(Bigint)匹配前缀和订单 此查询检索正确的结果(前缀为“11”): 但是我对跑步时间有一些问题 因此,我创建了3个索引: - CREATE INDEX naics_pattern_text_revenue_limit_idx ON Company (naics text_pattern_ops, revenue DESC NULLS LAST

在postgreSQL 9.3.4中,我有一个由~=1000万个元素组成的表公司。我想检索第一个10万家公司,
naics
(字符变化)通过
revenue
(Bigint)匹配前缀和订单

此查询检索正确的结果(前缀为“11”):

但是我对跑步时间有一些问题

因此,我创建了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\u pattern\u text\u revenue\u limit\u idx
但是
naics\u revenue\u desc\u idx
,并且不要在
naics\u revenue\u desc\u 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
运行时间为567.184毫秒(使用
naics\u pattern\u text\u idx
)和

运行时间为249.558毫秒(使用
naics\u revenue\u desc\u idx

所以我的问题是:

  • 有没有办法在postgreSQL正确考虑的
    naics
    revenue
    上创建索引

  • 我的印象是,postgreSQL应该能够在公司的较小子集上使用
    收入
    上的索引(一旦它被
    naics
    过滤)。我错过什么了吗


PS:我们(几乎)从不在公司表中插入新数据。我们只想优化
选择
无论
更新
插入
的开销是多少。

你能把工作量增加到足够高的程度吗?这样规划者就不会求助于外部合并(比如64MB)然后检查了吗?@JakubKania谢谢!这将运行时间除以2以上。现在postgre使用了
top-N heapsort内存
,这大大加快了速度。尽管如此,我仍然想知道为什么我的第一个多列索引没有被postgreSQL使用。您正在从167k候选行中选择前100k行。查询计划者可能刚刚决定用这种方式对它们进行排序会更快。如果你使用了一个更合理的限制(比如1k),它应该按照你想要的方式运行。如果要更频繁地使用WHERE子句,还可以尝试设置条件索引。
 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
SELECT c.* FROM Company c ORDER BY revenue DESC NULLS LAST LIMIT 100000