MySQL空間查詢(Geometry類)
效能測試:
一、建立支援查詢的表
建立一個包含空間資料的名為points的表。
CREATE TABLE points(
longitude DOUBLE,
latitude DOUBLE,
point POINT
);
這條命令建立一個名為points的表,包含一個longitude欄位,一個latitude欄位,一個point欄位。
二、向資料庫中匯入資料
因筆者已有一個包含經緯度的檔案log.csv。把log.csv匯入表log。
LOAD DATA INFILE 'C:\\log.csv'
INTO TABLE log
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '"'
LINES TERMINATED BY '\n';
把表log中的資料匯入新表points中
INSERT INTO points(longitude, latitude)SELECT longitude, latitude FROM log;
三、根據表points中的longitude,latitude欄位得到point欄位
UPDATE points SET point = GeomFromText(CONCAT('POINT(',points.longitude,' ',points.latitude,')'));
若報錯:Error Code: 1175. You are using safe update mode
and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Queries and reconnect.
先執行SET SQL_SAFE_UPDATES = 0;語句,然後執行上面語句。
四、從表中讀取資料
1、讀取表中的point欄位
SELECT AsText(point) FROM points;
以上語句的返回結果中的point會被轉換成GIS標準字串。實際上AsText函式僅僅是把資料庫內部儲存的幾何物件轉化為一個字串而已。
2、返回一系列point的X()(經度)小於10,並且Y()(緯度)小於10的點的集合
SELECT AsText(point) FROM points WHERE X(point) < 10 AND Y(point) < 10;
3、
四、測試效能
SELECT AsText(point) FROM points WHERE X(point) <13000000 and Y(point) > 60000000;
duration/fetch : 11.606sec/0.047sec
SELECT * FROM points WHERE longitude < 13000000 and latitude > 60000000;
duration/fetch : 11.2941sec/0.281sec
五、如果沒有資料也不必擔心,下面幫你製造資料
1、建立新表
CREATE TABLE `points` (
`name` varchar(20) NOT NULL DEFAULT '',
`location` point NOT NULL,
`description` varchar(200) DEFAULT NULL,
PRIMARY KEY (`name`),
SPATIAL KEY `sp_index` (`location`)
) ENGINE=MyISAM DEFAULT CHARSET=gbk;
2、寫函式
delimiter // -- 將SQL識別符號設為 '//'
CREATE PROCEDURE fill_points(
IN size INT(10)
)
BEGIN
DECLARE i DOUBLE(10,1) DEFAULT size;
DECLARE lon FLOAT(7,4);
DECLARE lat FLOAT(6,4);
DECLARE position VARCHAR(100);
DELETE FROM Points;
WHILE i > 0 DO
SET lon = RAND() * 360 - 180;
SET lat = RAND() * 180 - 90;
SET position = CONCAT( 'POINT(', lon, ' ', lat, ')' );
INSERT INTO Points(name, location) VALUES ( CONCAT('name_', i), GeomFromText(position) );
SET i = i - 1;
END WHILE;
END
3、生成資料
CALL fill_points(1000000);
4、查詢區域內的點
SET @center = GeomFromText('POINT(10 10)');
SET @radius = 30;
SET @bbox = CONCAT('POLYGON((',
X(@center) - @radius, ' ', Y(@center) - @radius, ',',
X(@center) + @radius, ' ', Y(@center) - @radius, ',',
X(@center) + @radius, ' ', Y(@center) + @radius, ',',
X(@center) - @radius, ' ', Y(@center) + @radius, ',',
X(@center) - @radius, ' ', Y(@center) - @radius, '))'
);
[1]
SELECT name, AsText(location)
FROM Points
WHERE Intersects( location, GeomFromText(@bbox) )
AND SQRT(POW( ABS( X(location) - X(@center)), 2) + POW( ABS(Y(location) - Y(@center)), 2 )) < @radius; To Obtain a result ordered by distance from the center of the selection area:
[2]
SELECT name, AsText(location), SQRT(POW( ABS( X(location) - X(@center)), 2) + POW( ABS(Y(location) - Y(@center)), 2 )) AS distance
FROM Points
WHERE Intersects( location, GeomFromText(@bbox) )
AND SQRT(POW( ABS( X(location) - X(@center)), 2) + POW( ABS(Y(location) - Y(@center)), 2 )) < @radius
ORDER BY distance;