之间和ORDER BY PostgreSQL的多列索引

问题描述 投票:0回答:1

我有大的表(100M记录)具有以下结构。

  length   |          created_at
-----------+-------------------------------
 506225551 | 2018-12-29 02:08:34.116618
 133712971 | 2018-10-19 21:20:14.568936
 608443439 | 2018-12-14 03:22:55.141416
 927160571 | 2019-01-30 00:51:41.639126
 407033524 | 2018-11-16 21:26:41.523047
 506008096 | 2018-11-17 00:07:42.839919
 457719749 | 2018-11-12 02:32:53.116225
  • 0 < length < 1000000000
  • '2017-01-01' < created_at < '2019-02-01'
  • 数据是均匀分布的lengthcreated_at

我想运行这样的查询

SELECT * FROM tbl WHERE length BETWEEN 2000000 and 3000000 ORDER BY  created_at DESC

有200万,3,000,000之间100K的结果,所以我想用指数来选择和排序。

我曾尝试这些方法

1.简单BTREE索引

create index on tbl(length);

这非常适用于短距离的length,但我不能使用这个索引订购的记录。

2.多列BTREE索引

 create index on tbl(length, created_at);

这个指数我只能使用像这样的查询

 SELECT * FROM tbl WHERE length = 2000000 ORDER BY  created_at DESC

3. GIST指数与btree_gist扩展。我希望,这个指标应该工作。

create index on tbl using gist(length, created_at);   

但事实并非如此。我不能用这个指数甚至像这样简单的查询。

test=# explain analyze select * from gist_test where a = 345 order by c desc;

                                                                QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=25706.37..25730.36 rows=9597 width=12) (actual time=4.839..5.568 rows=10000 loops=1)
   Sort Key: c DESC
   Sort Method: quicksort  Memory: 853kB
   ->  Bitmap Heap Scan on gist_test  (cost=370.79..25071.60 rows=9597 width=12) (actual time=1.402..2.869 rows=10000 loops=1)
         Recheck Cond: (a = 345)
         Heap Blocks: exact=152
         ->  Bitmap Index Scan on gist_test_a_b_c_idx  (cost=0.00..368.39 rows=9597 width=0) (actual time=1.384..1.384 rows=10000 loops=1)
               Index Cond: (a = 345)
 Planning time: 0.119 ms
 Execution time: 6.271 ms

我可以使用一列该指标只是作为简单的BTREE。

所以,我怎样才能解决这个问题?

也许有NoSQL数据库可以处理这样的疑问?

postgresql performance indexing nosql b-tree
1个回答
1
投票

我不认为这是可能的(至少在香草PostgreSQL的,我不知道的扩展,它可以帮助上)。排序记录的步骤可因为指数产生排序记录已经只有跳过。 然而:

  1. 正如在doc提到的,​​只有B树索引可用于排序(这是有意义的,它使用的是搜索树实现)。
  2. where和你order by是一个B树索引不兼容: 由于兼具条款,你需要把2列索引(A, B) (当(A, B)A仅这就是为什么PostgreSQL是能够快速索引扫描表)的索引数据由where排序,因此它也被A排序,但作为一个结果,它不是由B排序在索引(它是由B仅在每个子集,其中A是恒定的排序,而不是在整个表)。 正如你可能已经知道,在B具有索引只会是因为where的帮助不大。

为你上A的单个值滤波器的情况下的设置示例#2显示PostgreSQL是良好优化。

如果是不可接受的排序的两列(A, B),然后我怕你不应该期待比这更多。

© www.soinside.com 2019 - 2024. All rights reserved.