PostgreSQL:text\u pattern\u ops和Order by上的索引可以单独正常工作,但不在同一个SELECT中
在postgreSQL 9.3.4中,我有一个由~=1000万个元素组成的表公司。我想检索第一个10万家公司,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
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