由於在Geometry中,有相關自帶函數和SPATIAL INDEX的性能優化,可以讓某些位置計算的效率提升。以下是幾種計算方法的效果對比。
1. 數據准備
首先創建一個數據表,這是一個店鋪數據表,結構如下:
創建語句:
CREATE TABLE `store_geometry` (
`id` int(11) NOT NULL,
`name` varchar(64) NOT NULL,
`latitude` double DEFAULT NULL,
`longitude` double DEFAULT NULL,
`city` varchar(16) DEFAULT NULL,
`district` varchar(16) DEFAULT NULL,
`address` varchar(64) DEFAULT NULL,
`geohash_8` varchar(16) DEFAULT NULL,
`geometry` geometry DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
然后插入數據,包含id,name,latitude,longitude,city,district,address這些字段的數值。
原始字段數值插入后,通過geometry函數計算出geometry字段的數值,並更新:
UPDATE `store_geometry` SET geometry=geomFromText(CONCAT('POINT(',longitude,' ',latitude,')'))
到此,數據准備工作完成。
2. 對比實例:篩選出在一定矩形范圍內的店鋪
對比時,表內共有100,000條左右的店鋪數據。
矩形范圍:
max_x=121.474243
min_x=121.470724
max_y=31.234504
min_y=31.230229
2.1 方法一:使用經度和緯度字段判斷是否在此區間內
我們看看對latitude,longitude2個字段做索引前后的性能對比
先在索引前查詢:
SET @max_x=121.474243;
SET @min_x=121.470724;
SET @max_y=31.234504;
SET @min_y=31.230229;
SELECT * FROM `store_geometry` WHERE longitude BETWEEN @min_x AND @max_x and latitude BETWEEN @min_y AND @max_y;
查詢結果有70條,耗時0.473秒
然后索引后使用相同語句查詢,速度有明顯加快:
2.2 方法二:使用geometry字段數據和相關幾何計算函數判斷是否在此區間內
同樣的我們先不對geometry字段創建索引
SET @mbr=geomFromText(CONCAT('POLYGON','((',@min_x,' ',@min_y,',',@max_x,' ',@min_y,',',@max_x,' ',@max_y,',',@min_x,' ',@max_y,',',@min_x,' ',@min_y,'))'));
SELECT * FROM `store_geometry` WHERE st_contains(@mbr, geometry);
查詢結果相同,耗時如下:
然后對geometry創建索引,這里注意不要用mysql客戶端工具在界面上創建,因為只能創建普通索引,沒有效果。
CREATE SPATIAL INDEX i_geometry ON `store_geometry`(geometry);
然后用相同語句查詢,結果如下:
3.結論
實驗結果很明顯,geometry擴展在進行位置計算時具有性能上的明顯優勢。
方法 | 索引 | 查詢耗時(秒) |
使用經度和緯度字段 | no index | 0.473 |
index | 0.015 | |
使用geometry字段 | no index | 0.092 |
index | 0.008 |