用于地质点范围和数字范围查询的sql复合多列索引

lb3vh1jj  于 2021-07-29  发布在  Java
关注(0)|答案(1)|浏览(440)

我正在构建一个应用程序,服务器需要根据一些条件/过滤器选择行。其中之一是用户的位置和半径,用户希望看到的职位和其他过滤器,如日期范围和另一列的值过滤半径。这将是一个特别的事件发现应用程序。
我读过关于postgis的书,我知道有一个 point 数据类型。基于这个答案,我明白最好是从相等到范围列排序,尽管我觉得geo 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公里(假设前三行属于此区域)的公共事件,以及日期2020-07-05和2020-07-07之间的事件类型0、1或2。用户将获得id为2和3的行。
这是我想用适当的索引优化的查询。谢谢您!

ar5n3qh5

ar5n3qh51#

借助btree\u gist扩展,您可以将event\u type和start\u date列与event\u position一起包含到gist索引中。但是,只要限制子句类似于 event_type in (0, 1, 2) . (但是,如果列表只包含一个元素,它将被重写为一个相等的元素,在这种情况下,它可以有效地使用索引中的该列。)因此,使用其他两列将是我的出发点。我会把通常比较有选择性的放在第一位。如果你打算把过去的事情留在表中,而不是把它们清除掉,那么这个日期最终可能会更有选择性。
如果位置条件不是很有选择性(例如,你的大多数活动都在纽约,你的大多数用户都在纽约,几乎所有的东西都在100公里以内),那么你可能需要一种不同的方法。只需在上创建一个默认的btree索引 (event_type, start_date) . 与gist不同,这样的btree可以有效地使用 event_type in (0, 1, 2) 随着 AND start_date between x and y .
我不认为gist不能有效地使用in-list而btree可以的根本原因。也许这将是固定的要点在未来的一些版本。

相关问题