Dieser Artikel bietet Ihnen eine detaillierte Einführung in die MySQL-Funktion zur Geoverarbeitung (mit Code). Ich hoffe, dass er Ihnen als Referenz dienen wird.
Derzeit basieren immer mehr Unternehmen auf LBS, Personen in der Nähe, Take-out-Standorten, Geschäften in der Nähe usw. Jetzt werden wir die Lösung für das Geschäftsszenario besprechen, das mir am nächsten kommt.
Derzeit bekannte Lösungen sind:
Berechnung benutzerdefinierter MySQL-Funktionen, MySQL-Geo-Index, Mongodb-Geo-Index, Postgresql, PostGis-Index, Redis, GeoElasticSearchDieser Artikel testet die Leistung der MySQL-Funktionsoperation
Vorbereitungsarbeiten
Datentabelle erstellen
CREATE TABLE `driver` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `lng` float DEFAULT NULL, `lat` float DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Verstehen Sie grundlegende geografische Kenntnisse, bevor Sie Daten erstellen:
Bei gleichem Breitengrad:
Wenn die Längengrade gleich sind:
DELIMITER // CREATE DEFINER=`root`@`localhost` FUNCTION `getDistance`( `lng1` float(10,7) , `lat1` float(10,7) , `lng2` float(10,7) , `lat2` float(10,7) ) RETURNS double COMMENT '计算2坐标点距离' BEGIN declare d double; declare radius int; set radius = 6371000; #假设地球为正球形,直径为6371000米 set d = (2*ATAN2(SQRT(SIN((lat1-lat2)*PI()/180/2) *SIN((lat1-lat2)*PI()/180/2)+ COS(lat2*PI()/180)*COS(lat1*PI()/180) *SIN((lng1-lng2)*PI()/180/2) *SIN((lng1-lng2)*PI()/180/2)), SQRT(1-SIN((lat1-lat2)*PI()/180/2) *SIN((lat1-lat2)*PI()/180/2) +COS(lat2*PI()/180)*COS(lat1*PI()/180) *SIN((lng1-lng2)*PI()/180/2) *SIN((lng1-lng2)*PI()/180/2))))*radius; return d; END// DELIMITER ;
# coding=utf-8 from orator import DatabaseManager, Model import logging import random import threading """ 中国的经纬度范围 纬度3.86~53.55,经度73.66~135.05。大概0.00001度差距1米 """ # 创建 日志 对象 logger = logging.getLogger() handler = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.DEBUG) # Connect to the database config = { 'mysql': { 'driver': 'mysql', 'host': 'localhost', 'database': 'dbtest', 'user': 'root', 'password': '', 'prefix': '' } } db = DatabaseManager(config) Model.set_connection_resolver(db) class Driver(Model): __table__ = 'driver' __timestamps__ = False pass def ins_driver(thread_name,nums): logger.info('开启线程%s' % thread_name) for _ in range(nums): lng = '%.5f' % random.uniform(73.66, 135.05) lat = '%.5f' % random.uniform(3.86, 53.55) driver = Driver() driver.lng = lng driver.lat = lat driver.save() thread_nums = 10 for i in range(thread_nums): t = threading.Thread(target=ins_driver, args=(i, 400000)) t.start()
Das obige Skript erstellt 10 Threads und 10 Threads fügen 40.000 Daten ein. Die Ausführung dauerte 150,18 Sekunden und es wurden insgesamt 400.000 Datenelemente eingefügt
System: Mac OS
Speicher: 16G
CPU: Intel Core i5
Festplatte: 500g Solid State Drive
Finden Sie im Rahmen des Tests die 10 Treiber, die dem Koordinatenpunkt am nächsten liegen (134.38753,18.56734)
select *,`getDistance`(134.38753,18.56734,`lng`,`lat`) as dis from driver ORDER BY dis limit 10
Ich habe das Intervall von 10.000 bis 100.000 mal 10.000 getestet und von 100.000 auf 90 Änderungen der Ergebnisse alle 100.000 Tests
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung der MySQL-Funktion für die Geoverarbeitung von geografischen Standorten (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!