Postgres 9.4 哪种类型的索引最适合浮点列

Postgres 9.4 which type of index would be ideal for a float column

我在 mysql,现在加入了 postgres,我有一个 table,每天有多达 300,000 条新记录,但也有很多阅读。我有 2 列我认为最适合索引:纬度和经度,我知道 postgres 有不同类型的索引,我的问题是哪种类型的索引最适合有很多写入和读取的 table ?这是 reads

的查询
SELECT p.fullname,s.post,to_char(s.created_on, 'MON DD,YYYY'),last_reply,s.id,
r.my_id,s.comments,s.city,s.state,p.reputation,s.profile_id 
FROM profiles as p INNER JOIN streams as s ON (s.profile_id=p.id) Left JOIN 
reputation as r ON (r.stream_id=s.id and r.my_id=?) where s.latitudes >=? 
AND ?>= s.latitudes AND s.longitudes>=? AND ?>=s.longitudes order by 
s.last_reply desc limit ?"

如您所见,where 子句中的 2 列是纬度和经度

如果对纬度或经度列进行排序,您可能希望使用 B 树索引。

来自关于索引的 Postgres 文档页面:

B-trees can handle equality and range queries on data that can be sorted into some ordering. In particular, the PostgreSQL query planner will consider using a B-tree index whenever an indexed column is involved in a comparison using one of the [greater than / lesser than-type operators]

您可以阅读有关索引的更多信息 here

编辑:如果您需要对纬度和经度进行索引,一些 G* 索引看起来可能有用,因为它们似乎允许多维(例如 2d)索引。

Edit2:为了实际创建索引,您需要按照以下方式做一些事情(尽管您可能需要更改 table 名称以满足您的需要):

CREATE INDEX idx_lat ON s(latitudes);

请注意,B 树索引是默认索引,因此您无需指定类型。

阅读有关索引创建的更多信息here

PostgreSQL 有 point data type with many operators that have good support from the gist index。因此,如果可能的话,请更改您的 table 定义以使用 point 而不是 2 floats.

插入point数据非常简单,只需对列使用point(longitudes, latitudes),而不是将两个值放在不同的列中。与获取数据相同:lnglat[0] 是经度,lnglat[1] 是纬度。

索引应该是这样的:

CREATE INDEX idx_mytable_lnglat ON streams USING gist (lnglat pointops);

还有 box data type,这对于对所有参数进行分组非常有用,并且在框中查找点在 gist 索引中得到了高度优化。

在 table 中使用 point 并在 box 上进行搜索,您的查询将简化为:

SELECT p.fullname, s.post, to_char(s.created_on, 'MON DD,YYYY'), last_reply, s.id,
       r.my_id, s.comments, s.city, s.state, p.reputation, s.profile_id 
FROM profiles AS p
JOIN streams AS s ON (s.profile_id = p.id)
LEFT JOIN reputation AS r ON r.stream_id = s.id AND r.my_id = ?
WHERE s.lnglat && box(?, ?, ?, ?)
ORDER BY s.last_reply DESC
LIMIT ?;

短语s.lnglat && box(?, ?, ?, ?)表示"the value of column lnglat overlaps with (meaning: is inside) the box"。