我不是数据库专家,但我有足够的知识让自己陷入困境,就像这里的情况一样。此查询
SELECT DISTINCT p.*
FROM points p, areas a, contacts c
WHERE ( p.latitude > 43.6511659465
AND p.latitude < 43.6711659465
AND p.longitude > -79.4677941889
AND p.longitude < -79.4477941889)
AND p.resource_type = 'Contact'
AND c.user_id = 6
非常慢。 points表的记录少于2000条,但执行大约需要8秒。纬度和经度列上有索引。删除隐含resource_type和user_id的子句没有区别。
纬度和经度字段都被格式化为数字(15,10) - 我需要精度进行一些计算。
此项目中有许多其他查询,其中比较了点,但没有执行时间问题。发生了什么事?
答案 0 :(得分:11)
您是否忘记了实际查询中的内容?它缺少三个表之间的ANSI-89连接,为您提供笛卡尔积,但只提取POINTS记录。
答案 1 :(得分:5)
您正在加入三个表,p,a和c,但您没有指定如何将它们连接在一起。您得到的是在符合条件的所有表中的所有行之间的完整笛卡尔连接,然后是区域中的所有行。
您可能希望在某些区域附加某些内容。和...接触的东西......好吧,我不知道你的架构是什么样的。
尝试在开头粘贴“EXPLAIN”以获取有关正在发生的事情的信息。
答案 2 :(得分:3)
可能你错过了联接。加入这个表就是这样的。
SELECT DISTINCT p.*
FROM points p
JOIN areas a p ON a.FkPoint = p.id
JOIN contacts c ON c.FkArea = a.id
WHERE ( p.latitude > 43.6511659465
AND p.latitude < 43.6711659465
AND p.longitude > -79.4677941889
AND p.longitude < -79.4477941889)
AND p.resource_type = 'Contact'
AND c.user_id = 6
要获得更好的坐标索引,请使用四叉树或 R-Tree 索引实现。
如果您故意不错过联接,请尝试这样的子查询。
select DISTINCT thePoints.*
(
SELECT DISTINCT p.*
FROM points p
WHERE ( p.latitude > 43.6511659465
AND p.latitude < 43.6711659465
AND p.longitude > -79.4677941889
AND p.longitude < -79.4477941889)
AND p.resource_type = 'Contact'
) as thePoints
, areas, contacts
WHERE c.user_id = 6
答案 3 :(得分:0)
您需要rtree
索引并使用@
运算符,普通索引将不起作用。
R树 http://www.postgresql.org/docs/8.1/static/indexes-types.html
@
运营商
http://www.postgresql.org/docs/8.1/static/functions-geometry.html