пространственные данные и sql сервер: очень медленные запросы - PullRequest
0 голосов
/ 07 мая 2018

В настоящее время я использую SQL Server и у меня возникли проблемы, у меня есть таблица адресов с 12M адресов;когда я ищу один адрес;его займет 3 или 4 минуты, чтобы найти его.Я должен искать более 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 

Моя таблица:

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]

Оперативная память моего сервера: 128GB.

как я могу сделать этот запрос очень быстрым?или я должен использовать другой SGBD?

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Добавить новый столбец с точкой GPS типа GEOGRAPHY (вместо того, чтобы создавать его заново на каждом 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)

Создание пространственного индекса может занять некоторое время, если у вас много записей. Кроме того, для пространственного индекса требуется первичный ключ в этой таблице (его нужно будет создать, если у вас его еще нет).

Затем вы меняете свой выбор следующим образом:

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
0 голосов
/ 07 мая 2018

Вместо использования float для широты и долготы, почему бы не изменить структуру таблицы с помощью пространственных типов данных, таких как Geography или Geometry. Затем после вы можете использовать пространственный индекс на вновь созданной таблице.

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-spatial-index-transact-sql?view=sql-server-2017

...