Postgres 9.4哪种类型的索引适用于浮点列

时间:2015-10-08 02:09:43

标签: postgresql postgresql-9.4

我在mysql中,现在加入了postgres,我有一张桌子,每天最多可以获得300,000条新记录,但也有很多读取。我认为2列是理想的索引:纬度和经度我知道postgres有不同类型的索引,我的问题是哪种类型的索引最适合具有多个写入和读取的表?这是读取的查询

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列是纬度和经度

2 个答案:

答案 0 :(得分:3)

PostgreSQL的point data type有很多operators得到了gist index的良好支持。因此,如果可能的话,请更改您的表格定义,以使用point而不是2 float

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

索引将是这样的:

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

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

如果表格中有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(?, ?, ?, ?)表示"列lnglat的值与(#含义:在里面)框#34;重叠。

答案 1 :(得分:2)

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

关于索引的Postgres文档页面:

  

B树可以处理可以分类为某种排序的数据的相等和范围查询。特别是,只要使用[大于/小于类型的运算符]

之一进行比较,每当索引列涉及索引列时,PostgreSQL查询计划器就会考虑使用B树索引。

您可以阅读有关指数here的更多信息。

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

Edit2:为了真正创建索引,你想要做的事情(尽管你可能需要更改表名来满足你的需求):

CREATE INDEX idx_lat ON s(latitudes);

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

详细了解索引创建here