1

我正在尝试在 Java EE 中构建一个基于位置的应用程序,它从给定坐标的某个半径返回提供者作为输入。当我使用 JPA 时,我找不到使用命名查询来查询数据库的解决方案,因为它不支持 Sin、Cos 等函数。我在这里找到了一个不错的读物sql-havesine,我可以在其中使用本机而是查询。查询在数据库 (Postgres) 上执行速度很快(33 毫秒),但从应用程序执行时非常慢(> 800 毫秒)。

有没有办法从应用程序端加快速度,或者您是否必须使用数据库中的存储过程之类的东西。

我的方法如下所示:

@SuppressWarnings("unchecked")
public List<Company> findCompaniesByProximity(Coordinate coordinate, int distance) {
    double latitude = coordinate.getLatitude();
    double longitude = coordinate.getLongitude();
    String sql = "SELECT * FROM ("
            + "SELECT *, c.distance_unit * DEGREES(ACOS(COS(RADIANS(c.lat)) * COS(RADIANS(companies.latitude)) * "
            + "COS(RADIANS(c.lng) - RADIANS(companies.longitude)) + SIN(RADIANS(c.lat)) * SIN(RADIANS(companies.latitude)))"
            + ") AS distance "
            + "FROM Companies "
            + "JOIN (SELECT  ?1 AS lat, ?2 AS lng, ?3 AS search_radius, 111.045 AS distance_unit) "
            + "AS c ON 1=1 "
            + "WHERE companies.latitude "
            + "BETWEEN c.lat  - (c.search_radius / c.distance_unit) "
            + "AND c.lat  + (c.search_radius / c.distance_unit) "
            + "AND companies.longitude "
            + "BETWEEN c.lng - (c.search_radius / (c.distance_unit * COS(RADIANS(c.lat)))) "
            + "AND c.lng + (c.search_radius / (c.distance_unit * COS(RADIANS(c.lat))))"
            + ") AS proximity "
            + "WHERE distance <= search_radius "
            + "ORDER BY distance "
            + "LIMIT 25";
    List<Company> companies = null;
    try {
        Query query = em.createNativeQuery(sql, Company.class);
        query.setParameter(1, latitude);
        query.setParameter(2, longitude);
        query.setParameter(3, distance / 1000.0);
        companies = (List<Company>) query.getResultList();
    } catch (IllegalArgumentException e) {
        System.err.println("Argument is invalid " + e);
    } catch (PersistenceException e) {
        System.err.println("PersistenceException: " + e.getMessage());
    }
    return companies;
}

该方法是从单例 EJB 调用的,我将 Payara 服务器与 Postgres 和 EclipseLink 一起使用。一切都在本地调用,所以我认为与数据库的连接会快得多。我也尝试了 postgres earthdistance 扩展,但它更慢(> 1800 毫秒)。我对编程非常陌生,尤其是 Java EE,所以我可能在此过程中做错了什么:) 提前谢谢。

4

0 回答 0