空间数据和 sql 服务器:查询非常慢
spatial data and sql server : very slow queries
目前我正在使用 SQL 服务器并遇到问题,我有一个 table 地址,地址为 12M;当我寻找一个地址时;需要 3 或 4 分钟才能找到它。我每天必须在 table 中查找超过 40000 个地址。所以 Sql 服务器没有帮我解决这个问题。
我考虑使用其他 SGBD 也许 MongoDB,但我不知道它是否有效。我的目标是在 2 秒内找到每个查询。
我的查询:
SELECT TOP 1 adresse
FROM (SELECT
geography::Point(p.latitude, p.longitude,4326).STDistance(geography::Point(Cast(Replace('28,5259799957275', ',', '.') AS FLOAT)
, Cast(Replace('28,5259799957275', ',', '.') AS FLOAT), 4326)) AS rn,
p.adresse
FROM [adressespositions] p) ph
WHERE ph.rn < 10
我的table:
CREATE TABLE [dbo].[adressespositions](
[idgeocodage] [int] IDENTITY(1,1) NOT NULL,
[latitude] [float] NULL,
[longitude] [float] NULL,
[adresse] [nvarchar](100) NULL,
[dateajout] [datetime] NULL,
[source] [nvarchar](100) NULL,
[idsource] [int] NULL
) ON [PRIMARY]
我的服务器内存:128 GB。
我怎样才能使这个查询非常快?或者我必须使用其他 SGBD?
为什么不使用地理或几何等空间数据类型来更改 table 结构,而不是将浮点数用于纬度和经度。然后你可以在新创建的 table.
上使用空间索引
使用 GEOGRAPHY
类型的 GPS 点添加一个新列(而不是在每个 SELECT
上重新创建它)。然后在该列上创建一个 SPATIAL INDEX
,性能应该会飙升。
ALTER TABLE dbo.adressespositions ADD GPS GEOGRAPHY
UPDATE T SET
GPS = GEOGRAPHY::Point(T.latitude, T.longitude, 4326)
FROM
dbo.adressespositions AS T
CREATE SPATIAL INDEX SI_adressespositions_GPS ON dbo.adressespositions (GPS)
如果您有很多记录,创建空间索引可能需要一段时间。此外,空间索引需要一个主键 table(如果您还没有,则必须创建一个)。
然后您将 select 更改为如下所示:
DECLARE @FilterGPS GEOGRAPHY = GEOGRAPHY::Point(
Cast(Replace('28,5259799957275', ',', '.') AS FLOAT),
Cast(Replace('28,5259799957275', ',', '.') AS FLOAT),
4326)
SELECT TOP 1
P.adresse,
Distance = P.GPS.STDistance(@FilterGPS)
FROM
[adressespositions] AS P
WHERE
P.GPS.STDistance(@FilterGPS) < 10
ORDER BY
2 ASC
目前我正在使用 SQL 服务器并遇到问题,我有一个 table 地址,地址为 12M;当我寻找一个地址时;需要 3 或 4 分钟才能找到它。我每天必须在 table 中查找超过 40000 个地址。所以 Sql 服务器没有帮我解决这个问题。 我考虑使用其他 SGBD 也许 MongoDB,但我不知道它是否有效。我的目标是在 2 秒内找到每个查询。
我的查询:
SELECT TOP 1 adresse
FROM (SELECT
geography::Point(p.latitude, p.longitude,4326).STDistance(geography::Point(Cast(Replace('28,5259799957275', ',', '.') AS FLOAT)
, Cast(Replace('28,5259799957275', ',', '.') AS FLOAT), 4326)) AS rn,
p.adresse
FROM [adressespositions] p) ph
WHERE ph.rn < 10
我的table:
CREATE TABLE [dbo].[adressespositions](
[idgeocodage] [int] IDENTITY(1,1) NOT NULL,
[latitude] [float] NULL,
[longitude] [float] NULL,
[adresse] [nvarchar](100) NULL,
[dateajout] [datetime] NULL,
[source] [nvarchar](100) NULL,
[idsource] [int] NULL
) ON [PRIMARY]
我的服务器内存:128 GB。
我怎样才能使这个查询非常快?或者我必须使用其他 SGBD?
为什么不使用地理或几何等空间数据类型来更改 table 结构,而不是将浮点数用于纬度和经度。然后你可以在新创建的 table.
上使用空间索引使用 GEOGRAPHY
类型的 GPS 点添加一个新列(而不是在每个 SELECT
上重新创建它)。然后在该列上创建一个 SPATIAL INDEX
,性能应该会飙升。
ALTER TABLE dbo.adressespositions ADD GPS GEOGRAPHY
UPDATE T SET
GPS = GEOGRAPHY::Point(T.latitude, T.longitude, 4326)
FROM
dbo.adressespositions AS T
CREATE SPATIAL INDEX SI_adressespositions_GPS ON dbo.adressespositions (GPS)
如果您有很多记录,创建空间索引可能需要一段时间。此外,空间索引需要一个主键 table(如果您还没有,则必须创建一个)。
然后您将 select 更改为如下所示:
DECLARE @FilterGPS GEOGRAPHY = GEOGRAPHY::Point(
Cast(Replace('28,5259799957275', ',', '.') AS FLOAT),
Cast(Replace('28,5259799957275', ',', '.') AS FLOAT),
4326)
SELECT TOP 1
P.adresse,
Distance = P.GPS.STDistance(@FilterGPS)
FROM
[adressespositions] AS P
WHERE
P.GPS.STDistance(@FilterGPS) < 10
ORDER BY
2 ASC