例如,假设我有一张桌子:
Business(BusinessID, Lattitude, Longitude)
Run Code Online (Sandbox Code Playgroud)
当然,所有的都被索引了。还有100万条记录
例如,假设我想找到最接近 106,5 的商家,我该怎么做?
如果我做
SELECT *
FROM Business
WHERE (Some formula to compute distance here) < 2000
Run Code Online (Sandbox Code Playgroud)
例如,或者如果我这样做
SELECT *
FROM Business
TOP 20
Run Code Online (Sandbox Code Playgroud)
理论上,计算机必须计算所有业务的距离,而实际上只有经度和纬度在一定范围内的业务才需要计算。
那么我怎样才能在 PhP 或 SQL 中做我想做的事呢?
我很感激到目前为止的答案。我正在使用 mysql 并且他们没有比明显的解决方案更有效的方法。MySQL 空间也没有计算距离函数。
我有一张邮政编码表,其中包括每个邮政编码的中心纬度和 lng。我使用它从任意点获取给定英里半径内的邮政编码列表。
我突然想到,仅仅因为 zip 的中心点不在给定的半径内,并不意味着 zip 本身不在半径内。
我用我超高级的艺术技巧在这里说明了这一点:
绿色条纹斑点代表邮政编码 A、B 和 C。
红色污点是每个邮政编码的地理中心
紫红色圆点是目标位置,并且..
块状蓝色圆圈距离目标位置 1 英里
如果我对粉红色污迹 1 英里半径内的所有邮政编码运行查询,则仅返回邮政编码 B 和 C,因为 zip A 的中心点不在 1 英里半径内,即使粉红色污迹本身显然在邮政编码 A 中。
SELECT *,
p.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latpoint))
* COS(RADIANS(z.y))
* COS(RADIANS(p.longpoint) - RADIANS(z.x))
+ SIN(RADIANS(p.latpoint))
* SIN(RADIANS(z.y)))) AS dist
FROM standard_zip AS z
JOIN ( /* these are the query parameters */
SELECT $lat AS latpoint, $lng AS longpoint,
$miles AS radius, 69 AS distance_unit
) AS p ON 1=1
WHERE z.y …Run Code Online (Sandbox Code Playgroud) 我知道这里有类似的问题已经得到回答,但不幸的是,它们都不适合我。我正在通过创建一个页面来破解我的方式,该页面将在地图上显示多个位置。我正在使用 HTML 5 映射和 Google 地图。我已将我拥有的地址转换为 long/lat,并将它们与其他属性一起存储在 CSV 文件中。
我曾尝试存储为点、字符变化和数字以及尝试创建自己的定义,但没有成功。该表已经存在,我只需要添加这些额外的列。我宁愿不使用 PostGIS,因为这感觉就像增加了额外的复杂性级别,而我完全可以不用。
所以你有什么建议?
问题:
我有一个空间表(道路线),使用 ESRI 的SDE.ST_GEOMETRY用户定义数据类型存储在 Oracle 12c地理数据库中。我想列出线顶点,以便我最终可以访问和更新它们的坐标。如果我使用的是 SDO_GEOMETRY/Oracle Locator,那么我会使用该
SDO_UTIL.GETVERTICES函数。但是我没有使用 SDO_GEOMETRY/Oracle Locator,并且SDE.ST_GEOMETRY. 唯一的SDE.ST_GEOMETRY 功能,我可以找到属于顶点ST_PointN和ST_NumPoints。
我想出了一个成功完成所有这些的查询 - 将线顶点作为行(受此页面启发):
1 SELECT a.ROAD_ID
2 ,b.NUMBERS VERTEX_INDEX
3 ,a.SDE.ST_X(SDE.ST_PointN(a.SHAPE, b.NUMBERS)) AS X
4 ,a.SDE.ST_Y(SDE.ST_PointN(a.SHAPE, b.NUMBERS)) AS Y
5 FROM ENG.ROADS a
6 CROSS JOIN ENG.NUMBERS b
7 WHERE b.NUMBERS <= SDE.ST_NumPoints(a.SHAPE)
8 --removed to do explain plan: ORDER BY ROAD_ID, b.NUMBERS
----------------------------------------------------------------------------------------------------
| Id | Operation | Name …Run Code Online (Sandbox Code Playgroud) 我需要按距离从 InnoDb 表中获取记录(不能完全正确)并按距离排序。该表有 1000 万条记录。
到目前为止,我最好的时间是 8 秒(没有按距离排序的 3 秒),这使得它无法使用。我该如何改进?
我有一个定义为 SRID 4326 的点列。我使用的是 MySQL 8.0.12。
SELECT mp.hash_id,
ROUND(ST_Distance(ST_SRID(POINT(8.53955, 47.37706), 4326), mp.geo_pt), 2) AS distance
FROM member_profile mp
WHERE
MBRCONTAINS(ST_GeomFromText(
CONCAT('POLYGON((', ST_X(POINT (8.53955, 47.37706)) - 0.43415340086831, ' ',
ST_Y(POINT (8.53955, 47.37706)) - 0.43415340086831, ',',
ST_X(POINT (8.53955, 47.37706)) + 0.43415340086831, ' ',
ST_Y(POINT (8.53955, 47.37706)) - 0.43415340086831, ',',
ST_X(POINT (8.53955, 47.37706)) + 0.43415340086831, ' ',
ST_Y(POINT (8.53955, 47.37706)) + 0.43415340086831, ',',
ST_X(POINT (8.53955, 47.37706)) - 0.43415340086831, ' ',
ST_Y(POINT (8.53955, 47.37706)) …Run Code Online (Sandbox Code Playgroud) 我遇到了一个我无法解决的奇怪问题。服务器在执行一些 postgis 相关查询时崩溃。一些调试后,使用实例 提供由PostGIS的,它出现在ST_GEOMFROMGeoJSON()函数引起服务器崩溃。
崩溃:
SELECT ST_AsText(ST_GeomFromGeoJSON('{"type":"Point","coordinates":[-48.23456,20.12345]}')) As wkt;
Run Code Online (Sandbox Code Playgroud)
运行正常:
SELECT ST_AsText(
ST_Transform(
ST_GeomFromText('POLYGON((743238 2967416,743238 2967450,
743265 2967450,743265.625 2967416,743238 2967416))',2249)
,4326)
) As wgs_geom;
Run Code Online (Sandbox Code Playgroud)
查看日志时,我发现这些条目与崩溃相关:
2014-11-21 11:27:46 CET LOG: server process (PID 2377) was terminated by signal 11: Segmentation fault
2014-11-21 11:27:46 CET DETAIL: Failed process was running: SELECT ST_AsText(ST_GeomFromGeoJSON('{"type":"Point","coordinates":[-48.23456,20.12345]}')) As wkt;
2014-11-21 11:27:46 CET LOG: terminating any other active server processes
2014-11-21 11:27:46 CET WARNING: terminating connection because of crash of another server process
2014-11-21 …Run Code Online (Sandbox Code Playgroud) 我正在将一个点与一组多边形相交。查询已编入索引,多边形不重叠,但查询计划似乎认为我将返回 18k 行而不是 1 行,这会导致查询计划错误。
特别是查询计划的最右边节点似乎认为 STPointFromText 函数将返回 1000 的基数,并且该点集与几何索引的交集返回 54k 行的 30%。(在表格中运行了 100 万个点,但没有找到实际返回超过 1 行的反例)
这个缩写查询的结果并不可怕,但是当我将它的输出连接到其他任何东西时,高基数估计迫使上游表成为 tablescan+hashmap,即使整个查询返回 1 行。这个扩展查询每秒运行几次,所以我想知道如何优化它。
空间索引是 HHHH,对于大约 80x50 米的最高分辨率(在域的大约 4000 公里最长边上),索引中有 56k 个多边形,预计最小尺寸约为 100 米。
请注意 est 行和实际行之间的差异。
估计的查询计划。
我在存储过程执行期间使用以下结构创建临时表:
[ID] BIGINT
[Point] GEOGRAPHY
Run Code Online (Sandbox Code Playgroud)
该ID不是唯一的-大约有200每个记录ID。
我需要找到一个不同的列表,IDs其中至少有一个Point比Point常量值(例如200米)大的距离。
所以,我正在使用这样的东西:
SELECT DISTINCT DS1.[ID]
FROM DataSource DS1
INNER JOIN DataSource DS2
ON DS1.[ID] = DS2.[ID]
WHERE DS1.Point.STDistance(DS2.Point) > 200
Run Code Online (Sandbox Code Playgroud)
对于 23 000 个点,查询执行4-5几秒钟。因为我期待有更多的价值,所以我需要找到更好的解决方案。
我想如果有更快的方法,我总是可以创建一个物化表并实现额外的逻辑来计算它ID。
我创建了一个空间索引,但查询优化器没有使用它。如果我使用hint这样的WITH (INDEX(SPATIAL_idx_test))我会收到以下错误:
消息 8635,级别 16,状态 4,第 78 行
查询处理器无法为带有空间索引提示的查询生成查询计划。原因:空间索引不支持谓词中提供的比较器。尝试删除索引提示或删除SET FORCEPLAN. `
我对数据库管理还是个新手,我正在尝试优化搜索查询。
我有一个看起来像这样的查询,在某些情况下需要 5-15 秒来执行,并且还导致 100% 的 CPU 使用率:
DECLARE @point geography;
SET @point = geography::STPointFromText('POINT(3.3109015 6.648294)', 4326);
SELECT TOP (1)
[Result].[PointId] AS [PointId],
[Result].[PointName] AS [PointName],
[Result].[LegendTypeId] AS [LegendTypeId],
[Result].[GeoPoint] AS [GeoPoint]
FROM (
SELECT
[Extent1].[GeoPoint].STDistance(@point) AS distance,
[Extent1].[PointId] AS [PointId],
[Extent1].[PointName] AS [PointName],
[Extent1].[LegendTypeId] AS [LegendTypeId],
[Extent1].[GeoPoint] AS [GeoPoint]
FROM [dbo].[GeographyPoint] AS [Extent1]
WHERE 18 = [Extent1].[LegendTypeId]
) AS [Result]
ORDER By [Result].distance ASC
Run Code Online (Sandbox Code Playgroud)
该表在 PK 上有一个聚集索引,在geography类型列上有一个空间索引。
所以当我执行上述查询时,它正在执行扫描操作。
所以我在LegendTypeId列上创建了一个非聚集索引:
CREATE NONCLUSTERED INDEX [GeographyPoint_LegendType_NonClustered] ON [dbo].[GeographyPoint] …Run Code Online (Sandbox Code Playgroud) performance index sql-server optimization spatial query-performance
我有一个性能不佳的现有数据库解决方案。我正在使用浮点数等使用传统表结构搜索多维数据。数据库包含约 1-2M 行。
经过一番搜索,我发现了 SQL Server 空间数据类型,您可以在其中定义基于 Point 或 MultiPoint 的几何图形,您可以在其中进行距离搜索。我认为这可能是一个解决方案,但我需要一些帮助才能朝着正确的方向开始。
我当前的表结构如下,其中每行包含 2 个(最终更多)XYZ 值:
| ID | X1 | Y1 | Z1 | X2 | Y2 | Z2 |
| 1 | 1.1 | 2.2 | 5.1 | 1.2 | 2.1 | 4.1 |
| 2 | 3.2 | 5.1 | 4.1 | 3.2 | 3.1 | 3.1 |
| 3 | 4.1 | 2.3 | 6.3 | 4.2 | 4.1 | 2.1 |
| 4 | 2.4 | …Run Code Online (Sandbox Code Playgroud) spatial ×10
sql-server ×4
geometry ×3
mysql ×2
optimization ×2
performance ×2
postgresql ×2
datatypes ×1
index ×1
mysql-5.5 ×1
number-table ×1
oracle ×1
postgis ×1