入力として座標を指定すると、特定の半径からプロバイダーを返す Java EE でロケーションベースのアプリケーションを構築しようとしています。JPAを使用しているため、Sin、 Cosなどの関数をサポートしていないため、名前付きクエリでデータベースをクエリする解決策を見つけることができませんでした。代わりにクエリを実行します。クエリはデータベース (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にまったく慣れていないので、途中で何か間違ったことをしたかもしれません:)よろしくお願いします。