1

我正在构建一个应用程序,服务器需要根据某些标准/过滤器选择行。其中之一是用户的位置和用户希望查看帖子的半径以及其他过滤器,例如日期范围和过滤器以获取另一列的值。这将用于临时事件发现应用程序。

我已阅读有关 PostGIS 的信息,并且知道有一种point数据类型。基于这个答案,我明白最好从相等列到范围列排序,即使我觉得地理点列应该是第一个。但主要问题是,如何创建这样的索引?我考虑过 GiST 索引,但不确定是否有帮助。

假设如下简化事件表(忽略有效位置数据):

id  event_title                  event_position   event_type  is_public  start_date
    (varchar)                    (point lat/lon)  (smallint)  (boolean)  (timestamptz)
--  ---------------------------  ---------------  ---------   ---------  ----
 1  "John's Party"               (122,35)         0           0          2020-07-05
 2  "Revolution then Starbucks"  (123,30)         1           1          2020-07-06
 3  "Study for math exam"        (120,36)         2           1          2020-07-07
 4  "Party after exam"           (120,36)         1           1          2020-07-08
 5  "Hiking next to the city"    (95,40)          3           1          2020-07-09
 6  "Football match"             (-42,31)         4           1          2020-07-10

因此,在此表中,用户将能够查询接近 (122,34) 距离为 100 公里的公共事件(假设前三行属于该区域)以及事件类型 0、1 或 2 介于日期 2020-07-05 和2020-07-07。用户将获得 ID 为 2 和 3 的行。

这是我想用适当的索引优化的查询。谢谢!

4

1 回答 1

2

btree_gist 扩展的帮助下,您可以将 event_type 和 start_date 列与 event_position 一起包含到 GiST 索引中。但是,只要限制子句类似于event_type in (0, 1, 2). (但如果列表只包含一个元素,它将被重写为等式,在这种情况下,它可以有效地使用索引中的该列。)所以使用其他两列将是我的起点。我会把通常更有选择性的放在第一位。如果您打算将过去的事件留在表格中而不是清除它们,那么日期可能最终会成为更具选择性的日期。

如果位置条件根本不是很有选择性(例如,您的大多数活动都在纽约市,而您的大多数用户都在纽约市,并且几乎所有东西都在几乎所有其他东西的 100 公里范围内),那么您可能需要一种不同的方法。只需在(event_type, start_date). 与 GiST 不同,这样的 BTREE 可以有效地使用event_type in (0, 1, 2)with等条件AND start_date between x and y

我不认为 GiST 不能有效使用列表中的根本原因,而 BTREE 可以。也许这将在未来的某个版本中为 GiST 修复。

于 2020-07-05T14:44:06.350 回答