postgresql 关于geo 按距离排序返回 性能测试

本文展示了一个使用PostgreSQL 9.5.1版本进行地理空间数据查询的Java示例程序。该程序连接到PostgreSQL数据库,执行了针对1公里和5公里范围内的地理位置数据查询,并记录了查询耗时分别为650毫秒和1.2秒。测试环境配置为8GB内存,数据集大小约为1078000条记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


postgresql 9.5.1 版本

cpu  内存 8g;

数据量 :  1078000 ;

查询1km以内的点 

查询耗时 650毫秒

查询5km 以内的点

耗时 1.2s 左右


   public static void main(String[] args) {
        Connection c = null;
        try {
            Class.forName("org.postgresql.Driver");
            c = DriverManager
                    .getConnection("jdbc:postgresql://192.168.1.106:5432/postgres",
                            "Admin", "");
            //造数据
            double x=  0.002;
            double y = 0.002 ;
//            StringBuffer buffer = new StringBuffer("");
//            for (int i=50; i<100;i++){
//                for (int j =1000;j<10000;j++){
//                    buffer.append("INSERT INTO mylocation (geom,name,x,y) VALUES ( ")
//                            .append("  ST_GeomFromText('POINT(")
//                            .append(""+(x+i*0.001))
//                            .append(" ")
//                            .append(""+(y+j*0.001))
//                            .append(")', 4326),'zhangsan',")
//                            .append(""+(x+i*0.001)+","+(y+j*0.001)+");");
//                }
//            }
//           String sql = "INSERT INTO mylocation (geom,name,x,y) VALUES ( " +
//                    "  ST_GeomFromText('POINT(? ?)', 4326),'zhangsan',?,?  " +
//                    ");";
//            PreparedStatement preparedStatement = c.prepareStatement(buffer.toString());
//
//            boolean execute = preparedStatement.execute();
//            System.out.println(execute);






            String sql = "SELECT id, name,geom,x,y,   ST_DistanceSphere(  " +
                    "                      geom,  " +
                    "                      ST_GeometryFromText('POINT("+x+" "+ y+")')) distance  " +
                    "FROM mylocation  " +
                    "WHERE ST_DWithin(  " +
                    "  geom::geography,   " +
                    "  ST_GeomFromText('POINT("+x+""+ y+")', 4326)::geography,  " +
                    "  1000  " +
                    ") ORDER BY distance asc; " ;
            long pre = System.currentTimeMillis();
            PreparedStatement preparedStatement = c.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            int i = 0;
            while (resultSet.next()){
                i ++ ;
                System.out.println(resultSet.getInt(1)+" "+resultSet.getString(2)+" "+resultSet.getDouble(4)+" "+resultSet.getDouble(5));

            }
            long now = System.currentTimeMillis();
            System.out.println("total size: " + i +"总耗时:" +(now-pre));

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println(e.getClass().getName()+": "+e.getMessage());
            System.exit(0);
        }
        System.out.println("Opened database successfully");
    }


代码库: https://github.com/luosai001/postgresql



### 在Django中实现GPS距离计算并返回公里数的方法 在Django框架中实现GPS距离计算并返回公里数,可以通过以下步骤完成。这里以Haversine公式为基础实现精确计算(精度约±1米): #### 1. **创建距离计算工具函数** 在`utils/geo_utils.py`文件中添加Haversine公式实现: ```python import math def calculate_distance(lat1, lon1, lat2, lon2): """ 使用Haversine公式计算两个GPS点之间的距离(公里) 参数: lat1, lon1 - 第一个点的纬度和经度 lat2, lon2 - 第二个点的纬度和经度 返回: 公里数(保留2位小数) """ # 地球半径(公里) R = 6371.0 # 将角度转换为弧度 lat1 = math.radians(float(lat1)) lon1 = math.radians(float(lon1)) lat2 = math.radians(float(lat2)) lon2 = math.radians(float(lon2)) # 经纬度差值 dlat = lat2 - lat1 dlon = lon2 - lon1 # Haversine公式 a = math.sin(dlat/2)**2 + math.cos(lat1)*math.cos(lat2)*math.sin(dlon/2)**2 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) # 计算距离(公里) distance = R * c return round(distance, 2) # 保留两位小数 ``` #### 2. **在视图函数中使用距离计算** 在Django的视图函数中调用计算函数: ```python from django.http import JsonResponse from .utils.geo_utils import calculate_distance def calculate_gps_distance(request): # 获取查询参数 point1_lat = request.GET.get('lat1') point1_lon = request.GET.get('lon1') point2_lat = request.GET.get('lat2') point2_lon = request.GET.get('lon2') # 参数校验 if not all([point1_lat, point1_lon, point2_lat, point2_lon]): return JsonResponse({'error': '缺少经纬度参数'}, status=400) try: # 计算距离 distance_km = calculate_distance( point1_lat, point1_lon, point2_lat, point2_lon ) # 返回结果 return JsonResponse({ 'distance_km': distance_km, 'point1': {'lat': point1_lat, 'lon': point1_lon}, 'point2': {'lat': point2_lat, 'lon': point2_lon} }) except Exception as e: return JsonResponse({'error': str(e)}, status=500) ``` #### 3. **配置URL路由** 在`urls.py`文件中添加路由: ```python from django.urls import path from . import views urlpatterns = [ path('api/calculate-distance/', views.calculate_gps_distance, name='calculate_distance'), ] ``` #### 4. **与模型集成(可选)** 如果需要在模型层面直接计算距离,可以添加自定义方法: ```python from django.db import models from .utils.geo_utils import calculate_distance class Location(models.Model): name = models.CharField(max_length=100) latitude = models.FloatField() longitude = models.FloatField() def distance_to(self, other_location): """计算当前地点到另一个地点的距离""" return calculate_distance( self.latitude, self.longitude, other_location.latitude, other_location.longitude ) def __str__(self): return self.name ``` #### 5. **使用示例(测试API)** 通过HTTP请求测试接口: ```http GET /api/calculate-distance/?lat1=31.230416&lon1=121.473701&lat2=39.904214&lon2=116.407394 ``` 响应结果: ```json { "distance_km": 1068.54, "point1": {"lat": "31.230416", "lon": "121.473701"}, "point2": {"lat": "39.904214", "lon": "116.407394"} } ``` ### 性能优化建议 1. **批量计算优化** ```python def batch_calculate_distances(points): """ 批量计算多个点之间的距离矩阵 参数: 形式为[(lat1, lon1), (lat2, lon2), ...]的点列表 返回: N×N的距离矩阵(公里) """ n = len(points) matrix = [[0] * n for _ in range(n)] for i in range(n): for j in range(i+1, n): dist = calculate_distance(*points[i], *points[j]) matrix[i][j] = dist matrix[j][i] = dist return matrix ``` 2. **缓存计算结果**:对于经常查询的点位对,使用Django缓存 3. **使用PostGIS扩展**(如使用PostgreSQL): ```python # 在Django ORM中使用PostGIS函数 from django.contrib.gis.db.models.functions import Distance from django.contrib.gis.measure import D # 查询500公里范围内的点 nearby_locations = Location.objects.annotate( distance=Distance('point', my_location.point) ).filter(distance__lte=D(km=500)) ``` 对于类似于GPS记录跑步者跑过的总公里数
最新发布
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值