由于在 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 |
来源: http://www.bubuko.com/infodetail-2961902.html