使用Postgres中的floor()从大表中有效地进行选择

时间:2017-10-19 01:08:57

标签: postgresql

我有两个表:一个是正方形,在自然数上有x和y列,另一个在第一个表创建的网格上有点。示例模式:

Grid Table

id  | x | y
------------  
123 | 1 | 1  
234 | 1 | 2
345 | 2 | 1   
456 | 2 | 2

然后,points table

id |   x  |  y  
----------------
12 | 1.23 | 1.23
23 | 2.89 | 1.55  

目前,使用此查询:

SELECT g.* FROM grid as g, points as p  
WHERE p.id=23 AND floor(p.x)=g.x AND floor(p.y)=g.y;

我得到了预期的结果,即标识为23的点所在的网格方格(标识为345的网格);但是,当表grid有10,000,000行(我当前的情况)时,此查询令人难以置信地慢,即大约几秒钟。

我找到了一个解决方法,但这很难看:

SELECT g.* FROM grid as g, points as p  
WHERE p.id=23 AND (p.x-.5)::integer=g.x AND (p.y-.5)::integer=g.y;  

我再次获得了预期的结果,并且在11毫秒内,但这感觉很糟糕。有更干净的方法吗?任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:1)

您可以使用CTE,因为它只评估一次。

WITH p2 AS (select floor(p.x) x, 
                   floor(p.y) y 
            from points  p 
            where p.id=23)
SELECT  g.* 
FROM grid g
INNER JOIN  p2
ON p2.x=g.x and p2.y=g.y