以下查询返回我们附近的场所(纬度:62.0,lon:25.0),其范围内的半径按距离排序:
SELECT *, earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) AS distance FROM venues WHERE earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) <= radius ORDER BY earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon))
是否有可能(建议)重新使用earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon))SELECT的结果,而不是对SELECT,WHERE和ORDER BY子句分别进行计算?
earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon))
在GROUP BYandORDER BY子句中,您可以引用列别名(输出列),甚至可以引用SELECT列表项的序数。我引用以下手册ORDER BY:
GROUP BY
ORDER BY
SELECT
每个表达式可以是 输出列(SELECT列表项) 的 名称或序号 ,也可以是由输入列值组成的任意表达式。
大胆强调我的。
但是在WHEREandHAVING子句中,您只能引用基础表中的列(输入列),因此您必须拼写出函数调用。
WHERE
HAVING
SELECT *, earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) AS dist FROM venues WHERE earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) <= radius ORDER BY distance;
如果您想知道将计算打包到CTE或子查询中是否更快,请使用进行测试EXPLAIN ANALYZE。(我对此表示怀疑。)
EXPLAIN ANALYZE
SELECT * FROM ( SELECT * ,earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) AS dist FROM venues ) x WHERE distance <= radius ORDER BY distance;
就像@Mike commented一样,通过声明一个函数STABLE(或IMMUTABLE),您可以通知查询计划者,函数调用的结果可以在同一条语句中多次重复用于相同的调用。我在这里引用手册:
STABLE
IMMUTABLE
STABLE函数无法修改数据库,并且在给定单个语句内所有行的给定相同参数的情况下,保证返回相同的结果。此类别 使优化程序可以将函数的多个调用优化为单个调用 。