之前一直做记录地点的坐标,都是使用一个lat 一个 long 的浮点型来计算。这样计算是有偏差的,所以尝试了一下GEOMETRY 的数据(另外一个更加贴切的地理类型是GEOGRAPHY,如果用来存坐标,其实使用起来比较类似,但是这次先不说)
DECLARE
@GEO1 GEOMETRY,
@GEO2 GEOMETRY
从简单的说起,这里我定义了2个点,求出2个点的距离
SELECT @GEO1=GEOMETRY::STGeomFromText('POINT(1 1 1)',0),
@GEO2=GEOMETRY::STGeomFromText('POINT(2 2 2)',0)
--Distance的方法和Z点和M点的值无关,并且Distance的计算距离也可以使用几何公式计算出一样的结果。
SELECT @GEO1.STDistance(@GEO2),
POWER(POWER(@GEO1.STX-@GEO2.STX,2)+POWER(@GEO1.STY-@GEO2.STY,2),0.5) --还记得两点之间的距离公式吗_(:з」∠)_,忽然感觉对不起数学老师
Distance 公式
---------------------- ----------------------
1.4142135623731 1.4142135623731
1.4142135623731 1.4142135623731
*其实就是根号2 ╮(╯_╰)╭。
*还有一点,Distance的方法只对应X,Y坐标有效。对于Z,M这2个坐标系是无关的。
然而实际在运算效率上,简单点的运算可以先取值然后再套公式进行运算,比起直接使用Distance会快不少。
比如这样
DECLARE @GEO1 GEOMETRY, @GEO2 GEOMETRY, @Lat1 FLOAT, @Long1 FLOAT, @Lat2 FLOAT, @Long2 FLOAT SELECT @GEO1=GEOMETRY::STGeomFromText('POINT(1 1 1)',0), @GEO2=GEOMETRY::STGeomFromText('POINT(2 2 2)',0) SELECT @GEO1.STDistance(@GEO2) --,@GEO1,@GEO2 SELECT @Lat1 = @GEO1.STX, @Long1 = @GEO1.STY, @Lat2 = @GEO2.STX, @Long2 = @GEO2.STY SELECT POWER(POWER(@Lat1-@Lat2,2) + POWER(@Long1-@Long2,2),0.5)
其实结果是一样的,但是看下执行计划,直接调用Distance的方法占用运算比例就100%了。如果在数据量比较大的时候,这个运算带来的性能差异就会越来越明显。所以如果是简单应用的话,可以考虑直接套用几何公式而不要直接调用函数,当然也可以看下能否使用空间索引
参考地址:https://msdn.microsoft.com/zh-cn/library/ff929109(v=sql.120).aspx
*HasZ ,HasM 的方法是12以上版本才提供